diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index 7128631e6..3ff5aaf65 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -490,7 +490,7 @@ class RepositoriesController < ApplicationController end def check_share_permissions - render_403 if !can_share_repository?(@repository) || current_user.teams.count <= 1 + render_403 unless can_share_repository?(@repository) end def repository_params diff --git a/app/controllers/team_repositories_controller.rb b/app/controllers/team_repositories_controller.rb index bd6d99ff1..2a50473dc 100644 --- a/app/controllers/team_repositories_controller.rb +++ b/app/controllers/team_repositories_controller.rb @@ -6,11 +6,11 @@ class TeamRepositoriesController < ApplicationController # DELETE :team_id/repositories/:repository_id/team_repositories/:id def destroy - team_repository = @repository.team_repositories.find_by_id(destory_params[:id]) + team_shared_object = @repository.team_shared_objects.find_by(id: destory_params[:id]) - if team_repository - log_activity(:unshare_inventory, team_repository) - team_repository.destroy + if team_shared_object + log_activity(:unshare_inventory, team_shared_object) + team_shared_object.destroy! render json: {}, status: :no_content else render json: { message: I18n.t('repositories.multiple_share_service.nothing_to_delete') }, @@ -89,14 +89,14 @@ class TeamRepositoriesController < ApplicationController } end - def log_activity(type_of, team_repository) + def log_activity(type_of, team_shared_object) Activities::CreateActivityService .call(activity_type: type_of, owner: current_user, - subject: team_repository.repository, + subject: team_shared_object.shared_repository, team: current_team, - message_items: { repository: team_repository.repository.id, - team: team_repository.team.id, + message_items: { repository: team_shared_object.shared_repository.id, + team: team_shared_object.team.id, permission_level: Extends::SHARED_INVENTORIES_PL_MAPPINGS[team_repository.permission_level.to_sym] }) end diff --git a/app/models/concerns/permission_checkable_model.rb b/app/models/concerns/permission_checkable_model.rb index 174748990..f528f4e0e 100644 --- a/app/models/concerns/permission_checkable_model.rb +++ b/app/models/concerns/permission_checkable_model.rb @@ -24,9 +24,11 @@ module PermissionCheckableModel def load_user_role_permissions(user) if user_assignments.loaded? - user_assignments.detect { |user_assignment| user_assignment.user == user }&.user_role&.permissions + user_assignments.detect do |user_assignment| + user_assignment.user == user && user_assignment.team == user.current_team + end&.user_role&.permissions else - user_assignments.find_by(user: user)&.user_role&.permissions + user_assignments.find_by(user: user, team: user.current_team)&.user_role&.permissions end end end diff --git a/app/models/repository.rb b/app/models/repository.rb index 3d7536f9f..2cf174609 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -42,11 +42,11 @@ class Repository < RepositoryBase scope :archived, -> { where(archived: true) } scope :accessible_by_teams, lambda { |teams| - accessible_repositories = left_outer_joins(:team_repositories) + accessible_repositories = left_outer_joins(:team_shared_objects) accessible_repositories = accessible_repositories .where(team: teams) - .or(accessible_repositories.where(team_repositories: { team: teams })) + .or(accessible_repositories.where(team_shared_objects: { team: teams })) .or(accessible_repositories .where(permission_level: [Extends::SHARED_INVENTORIES_PERMISSION_LEVELS[:shared_read], Extends::SHARED_INVENTORIES_PERMISSION_LEVELS[:shared_write]])) @@ -126,7 +126,7 @@ class Repository < RepositoryBase end def shared_with_anybody? - (!not_shared? || team_repositories.any?) + (!not_shared? || team_shared_objects.any?) end def shared_with?(team) @@ -144,15 +144,15 @@ class Repository < RepositoryBase def shared_with_read?(team) return false if self.team == team - shared_read? || team_repositories.where(team: team, permission_level: :shared_read).any? + shared_read? || team_shared_objects.where(team: team, permission_level: :shared_read).any? end def private_shared_with?(team) - team_repositories.where(team: team).any? + team_shared_objects.where(team: team).any? end def private_shared_with_write?(team) - team_repositories.where(team: team, permission_level: :shared_write).any? + team_shared_objects.where(team: team, permission_level: :shared_write).any? end def self.viewable_by_user(_user, teams) diff --git a/app/models/team_shared_object.rb b/app/models/team_shared_object.rb index 3be9a3956..868d25213 100644 --- a/app/models/team_shared_object.rb +++ b/app/models/team_shared_object.rb @@ -3,18 +3,22 @@ class TeamSharedObject < ApplicationRecord enum permission_level: Extends::SHARED_OBJECTS_PERMISSION_LEVELS.except(:not_shared) + after_create :assign_shared_inventories, if: -> { shared_object.is_a?(Repository) } + before_destroy :unassign_unshared_items, if: -> { shared_object.is_a?(Repository) } + before_destroy :unassign_unshared_inventories, if: -> { shared_object.is_a?(Repository) } + belongs_to :team - belongs_to :shared_object, polymorphic: true + belongs_to :shared_object, polymorphic: true, inverse_of: :team_shared_objects belongs_to :shared_repository, (lambda do |team_shared_object| - team_shared_object.shared_object_type == 'RepositoryBAse' ? self : none + team_shared_object.shared_object_type == 'RepositoryBase' ? self : none end), - optional: true, foreign_key: :shared_object_id, inverse_of: :team_shared_object - - before_destroy :unassign_unshared_items, if: -> { shared_object.is_a?(Repository) } + optional: true, + class_name: 'RepositoryBase', + foreign_key: :shared_object_id validates :permission_level, presence: true - validates :shared_object, uniqueness: { scope: :team_id } + validates :shared_object_type, uniqueness: { scope: %i(shared_object_id team_id) } validate :team_cannot_be_the_same private @@ -23,13 +27,30 @@ class TeamSharedObject < ApplicationRecord errors.add(:team_id, :same_team) if shared_object.team.id == team_id end + def assign_shared_inventories + viewer_role = UserRole.find_by(name: UserRole.public_send('viewer_role').name) + normal_user_role = UserRole.find_by(name: UserRole.public_send('normal_user_role').name) + + team.users.find_each do |user| + shared_object.user_assignments.create!( + user: user, + user_role: shared_write? ? normal_user_role : viewer_role, + team: team + ) + end + end + def unassign_unshared_items - return if repository.shared_read? || repository.shared_write? + return if shared_object.shared_read? || shared_object.shared_write? MyModuleRepositoryRow.joins(my_module: { experiment: { project: :team } }) .joins(repository_row: :repository) .where(my_module: { experiment: { projects: { team: team } } }) - .where(repository_rows: { repository: repository }) + .where(repository_rows: { repository: shared_object }) .destroy_all end + + def unassign_unshared_inventories + team.repository_sharing_user_assignments.where(assignable: shared_object).find_each(&:destroy!) + end end diff --git a/app/services/repositories/multiple_share_update_service.rb b/app/services/repositories/multiple_share_update_service.rb index 9599e9b97..26453a0f8 100644 --- a/app/services/repositories/multiple_share_update_service.rb +++ b/app/services/repositories/multiple_share_update_service.rb @@ -33,18 +33,17 @@ module Repositories if !@shared_with_all.nil? && !@shared_permission_level.nil? old_permission_level = @repository.permission_level @repository.permission_level = @shared_with_all ? @shared_permission_level : :not_shared - if @repository.changed? - log_activity_share_all(@repository.permission_level, old_permission_level, @repository) if @repository.save + if @repository.changed? && @repository.save + log_activity_share_all(@repository.permission_level, old_permission_level, @repository) end end @team_ids_for_share.each do |share| - team_repository = TeamRepository.new(repository: @repository, - team_id: share[:id], - permission_level: share[:permission_level]) + team_shared_object = + @repository.team_shared_objects.new(team_id: share[:id], permission_level: share[:permission_level]) - if team_repository.save - log_activity(:share_inventory, team_repository) + if team_shared_object.save + log_activity(:share_inventory, team_shared_object) else warnings << I18n.t('repositories.multiple_share_service.unable_to_share', repository: @repository.name, team: share[:id]) @@ -52,11 +51,11 @@ module Repositories end @team_ids_for_unshare.each do |team_id| - team_repository = TeamRepository.where(repository: @repository, team_id: team_id).first + team_shared_object = @repository.team_shared_objects.find_by(team_id: team_id) - if team_repository - log_activity(:unshare_inventory, team_repository) - team_repository.destroy + if team_shared_object + log_activity(:unshare_inventory, team_shared_object) + team_shared_object.destroy! else warnings << I18n.t('repositories.multiple_share_service.unable_to_unshare', repository: @repository.name, team: team_id) @@ -64,11 +63,11 @@ module Repositories end @team_ids_for_update.each do |update| - team_repository = TeamRepository.where(repository: @repository, team_id: update[:id]).first - team_repository.permission_level = update[:permission_level] if team_repository + team_shared_object = @repository.team_shared_objects.find_by(team_id: update[:id]) + team_shared_object.permission_level = update[:permission_level] if team_shared_object - if team_repository&.save - log_activity(:update_share_inventory, team_repository) + if team_shared_object&.save + log_activity(:update_share_inventory, team_shared_object) else warnings << I18n.t('repositories.multiple_share_service.unable_to_update', repository: @repository.name, team: update[:id]) @@ -98,16 +97,16 @@ module Repositories true end - def log_activity(type_of, team_repository) + def log_activity(type_of, team_shared_object) Activities::CreateActivityService .call(activity_type: type_of, owner: @user, - subject: team_repository.repository, + subject: team_shared_object.shared_object, team: @team, - message_items: { repository: team_repository.repository.id, - team: team_repository.team.id, + message_items: { repository: team_shared_object.shared_object.id, + team: team_shared_object.team.id, permission_level: - Extends::SHARED_INVENTORIES_PL_MAPPINGS[team_repository.permission_level.to_sym] }) + Extends::SHARED_INVENTORIES_PL_MAPPINGS[team_shared_object.permission_level.to_sym] }) end def log_activity_share_all(permission_level, old_permission_level, repository) diff --git a/app/views/repositories/show.html.erb b/app/views/repositories/show.html.erb index 525262562..d3576340a 100644 --- a/app/views/repositories/show.html.erb +++ b/app/views/repositories/show.html.erb @@ -49,7 +49,7 @@
- <% if can_share_repository?(@repository) && current_user.teams.count > 1 %> + <% if can_share_repository?(@repository) %> <%= link_to team_repository_share_modal_path(current_team, repository_id: @repository), class: 'btn btn-light share-repo-option', remote: true, id: 'shareRepoBtn' do %> diff --git a/db/migrate/20220516111152_add_team_level_permissions.rb b/db/migrate/20220516111152_add_team_level_permissions.rb index e72930649..5bcf9725d 100644 --- a/db/migrate/20220516111152_add_team_level_permissions.rb +++ b/db/migrate/20220516111152_add_team_level_permissions.rb @@ -77,7 +77,7 @@ class AddTeamLevelPermissions < ActiveRecord::Migration[6.1] @viewer_role.permissions = @viewer_role.permissions - VIEWER_PERMISSIONS @viewer_role.save(validate: false) - UserAssignment.where(assignable_type: %w(Team Protocol Report Repository)).delete_all + UserAssignment.where(assignable_type: %w(Team Protocol Report RepositoryBase)).delete_all end end end