Update repository sharing actions [SCI-6918]

This commit is contained in:
Oleksii Kriuchykhin 2022-07-01 11:55:27 +02:00
parent 3fbc5af9a1
commit 17178c28d5
8 changed files with 69 additions and 47 deletions

View file

@ -490,7 +490,7 @@ class RepositoriesController < ApplicationController
end end
def check_share_permissions def check_share_permissions
render_403 if !can_share_repository?(@repository) || current_user.teams.count <= 1 render_403 unless can_share_repository?(@repository)
end end
def repository_params def repository_params

View file

@ -6,11 +6,11 @@ class TeamRepositoriesController < ApplicationController
# DELETE :team_id/repositories/:repository_id/team_repositories/:id # DELETE :team_id/repositories/:repository_id/team_repositories/:id
def destroy 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 if team_shared_object
log_activity(:unshare_inventory, team_repository) log_activity(:unshare_inventory, team_shared_object)
team_repository.destroy team_shared_object.destroy!
render json: {}, status: :no_content render json: {}, status: :no_content
else else
render json: { message: I18n.t('repositories.multiple_share_service.nothing_to_delete') }, render json: { message: I18n.t('repositories.multiple_share_service.nothing_to_delete') },
@ -89,14 +89,14 @@ class TeamRepositoriesController < ApplicationController
} }
end end
def log_activity(type_of, team_repository) def log_activity(type_of, team_shared_object)
Activities::CreateActivityService Activities::CreateActivityService
.call(activity_type: type_of, .call(activity_type: type_of,
owner: current_user, owner: current_user,
subject: team_repository.repository, subject: team_shared_object.shared_repository,
team: current_team, team: current_team,
message_items: { repository: team_repository.repository.id, message_items: { repository: team_shared_object.shared_repository.id,
team: team_repository.team.id, team: team_shared_object.team.id,
permission_level: permission_level:
Extends::SHARED_INVENTORIES_PL_MAPPINGS[team_repository.permission_level.to_sym] }) Extends::SHARED_INVENTORIES_PL_MAPPINGS[team_repository.permission_level.to_sym] })
end end

View file

@ -24,9 +24,11 @@ module PermissionCheckableModel
def load_user_role_permissions(user) def load_user_role_permissions(user)
if user_assignments.loaded? 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 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 end
end end

View file

@ -42,11 +42,11 @@ class Repository < RepositoryBase
scope :archived, -> { where(archived: true) } scope :archived, -> { where(archived: true) }
scope :accessible_by_teams, lambda { |teams| 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 =
accessible_repositories accessible_repositories
.where(team: teams) .where(team: teams)
.or(accessible_repositories.where(team_repositories: { team: teams })) .or(accessible_repositories.where(team_shared_objects: { team: teams }))
.or(accessible_repositories .or(accessible_repositories
.where(permission_level: [Extends::SHARED_INVENTORIES_PERMISSION_LEVELS[:shared_read], .where(permission_level: [Extends::SHARED_INVENTORIES_PERMISSION_LEVELS[:shared_read],
Extends::SHARED_INVENTORIES_PERMISSION_LEVELS[:shared_write]])) Extends::SHARED_INVENTORIES_PERMISSION_LEVELS[:shared_write]]))
@ -126,7 +126,7 @@ class Repository < RepositoryBase
end end
def shared_with_anybody? def shared_with_anybody?
(!not_shared? || team_repositories.any?) (!not_shared? || team_shared_objects.any?)
end end
def shared_with?(team) def shared_with?(team)
@ -144,15 +144,15 @@ class Repository < RepositoryBase
def shared_with_read?(team) def shared_with_read?(team)
return false if self.team == 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 end
def private_shared_with?(team) def private_shared_with?(team)
team_repositories.where(team: team).any? team_shared_objects.where(team: team).any?
end end
def private_shared_with_write?(team) 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 end
def self.viewable_by_user(_user, teams) def self.viewable_by_user(_user, teams)

View file

@ -3,18 +3,22 @@
class TeamSharedObject < ApplicationRecord class TeamSharedObject < ApplicationRecord
enum permission_level: Extends::SHARED_OBJECTS_PERMISSION_LEVELS.except(:not_shared) 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 :team
belongs_to :shared_object, polymorphic: true belongs_to :shared_object, polymorphic: true, inverse_of: :team_shared_objects
belongs_to :shared_repository, belongs_to :shared_repository,
(lambda do |team_shared_object| (lambda do |team_shared_object|
team_shared_object.shared_object_type == 'RepositoryBAse' ? self : none team_shared_object.shared_object_type == 'RepositoryBase' ? self : none
end), end),
optional: true, foreign_key: :shared_object_id, inverse_of: :team_shared_object optional: true,
class_name: 'RepositoryBase',
before_destroy :unassign_unshared_items, if: -> { shared_object.is_a?(Repository) } foreign_key: :shared_object_id
validates :permission_level, presence: true 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 validate :team_cannot_be_the_same
private private
@ -23,13 +27,30 @@ class TeamSharedObject < ApplicationRecord
errors.add(:team_id, :same_team) if shared_object.team.id == team_id errors.add(:team_id, :same_team) if shared_object.team.id == team_id
end 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 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 } }) MyModuleRepositoryRow.joins(my_module: { experiment: { project: :team } })
.joins(repository_row: :repository) .joins(repository_row: :repository)
.where(my_module: { experiment: { projects: { team: team } } }) .where(my_module: { experiment: { projects: { team: team } } })
.where(repository_rows: { repository: repository }) .where(repository_rows: { repository: shared_object })
.destroy_all .destroy_all
end end
def unassign_unshared_inventories
team.repository_sharing_user_assignments.where(assignable: shared_object).find_each(&:destroy!)
end
end end

View file

@ -33,18 +33,17 @@ module Repositories
if !@shared_with_all.nil? && !@shared_permission_level.nil? if !@shared_with_all.nil? && !@shared_permission_level.nil?
old_permission_level = @repository.permission_level old_permission_level = @repository.permission_level
@repository.permission_level = @shared_with_all ? @shared_permission_level : :not_shared @repository.permission_level = @shared_with_all ? @shared_permission_level : :not_shared
if @repository.changed? if @repository.changed? && @repository.save
log_activity_share_all(@repository.permission_level, old_permission_level, @repository) if @repository.save log_activity_share_all(@repository.permission_level, old_permission_level, @repository)
end end
end end
@team_ids_for_share.each do |share| @team_ids_for_share.each do |share|
team_repository = TeamRepository.new(repository: @repository, team_shared_object =
team_id: share[:id], @repository.team_shared_objects.new(team_id: share[:id], permission_level: share[:permission_level])
permission_level: share[:permission_level])
if team_repository.save if team_shared_object.save
log_activity(:share_inventory, team_repository) log_activity(:share_inventory, team_shared_object)
else else
warnings << I18n.t('repositories.multiple_share_service.unable_to_share', warnings << I18n.t('repositories.multiple_share_service.unable_to_share',
repository: @repository.name, team: share[:id]) repository: @repository.name, team: share[:id])
@ -52,11 +51,11 @@ module Repositories
end end
@team_ids_for_unshare.each do |team_id| @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 if team_shared_object
log_activity(:unshare_inventory, team_repository) log_activity(:unshare_inventory, team_shared_object)
team_repository.destroy team_shared_object.destroy!
else else
warnings << I18n.t('repositories.multiple_share_service.unable_to_unshare', warnings << I18n.t('repositories.multiple_share_service.unable_to_unshare',
repository: @repository.name, team: team_id) repository: @repository.name, team: team_id)
@ -64,11 +63,11 @@ module Repositories
end end
@team_ids_for_update.each do |update| @team_ids_for_update.each do |update|
team_repository = TeamRepository.where(repository: @repository, team_id: update[:id]).first team_shared_object = @repository.team_shared_objects.find_by(team_id: update[:id])
team_repository.permission_level = update[:permission_level] if team_repository team_shared_object.permission_level = update[:permission_level] if team_shared_object
if team_repository&.save if team_shared_object&.save
log_activity(:update_share_inventory, team_repository) log_activity(:update_share_inventory, team_shared_object)
else else
warnings << I18n.t('repositories.multiple_share_service.unable_to_update', warnings << I18n.t('repositories.multiple_share_service.unable_to_update',
repository: @repository.name, team: update[:id]) repository: @repository.name, team: update[:id])
@ -98,16 +97,16 @@ module Repositories
true true
end end
def log_activity(type_of, team_repository) def log_activity(type_of, team_shared_object)
Activities::CreateActivityService Activities::CreateActivityService
.call(activity_type: type_of, .call(activity_type: type_of,
owner: @user, owner: @user,
subject: team_repository.repository, subject: team_shared_object.shared_object,
team: @team, team: @team,
message_items: { repository: team_repository.repository.id, message_items: { repository: team_shared_object.shared_object.id,
team: team_repository.team.id, team: team_shared_object.team.id,
permission_level: 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 end
def log_activity_share_all(permission_level, old_permission_level, repository) def log_activity_share_all(permission_level, old_permission_level, repository)

View file

@ -49,7 +49,7 @@
</div> </div>
<div class="repo-datatables-buttons"> <div class="repo-datatables-buttons">
<div class="share-repository-button" data-view-mode="active"> <div class="share-repository-button" data-view-mode="active">
<% 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), <%= link_to team_repository_share_modal_path(current_team, repository_id: @repository),
class: 'btn btn-light share-repo-option', remote: true, id: 'shareRepoBtn' do %> class: 'btn btn-light share-repo-option', remote: true, id: 'shareRepoBtn' do %>
<span class="fas fa-user-plus"></span> <span class="fas fa-user-plus"></span>

View file

@ -77,7 +77,7 @@ class AddTeamLevelPermissions < ActiveRecord::Migration[6.1]
@viewer_role.permissions = @viewer_role.permissions - VIEWER_PERMISSIONS @viewer_role.permissions = @viewer_role.permissions - VIEWER_PERMISSIONS
@viewer_role.save(validate: false) @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 end
end end