mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-11 15:45:34 +08:00
Implement public user grouping, deletion and updates to manually assigned [SCI-6228] (#3701)
* Implement public user grouping, deletion and updates to manually assigned [SCI-6228] * PR fixes [SCI-6228] * Permission check improvement [SCI-6228]
This commit is contained in:
parent
62d4d8e36e
commit
78ab094bf2
14 changed files with 110 additions and 26 deletions
|
@ -49,6 +49,7 @@
|
|||
|
||||
.user-assignment-remove {
|
||||
margin-left: 1em;
|
||||
min-width: 7em;
|
||||
}
|
||||
|
||||
a,
|
||||
|
|
|
@ -4,10 +4,16 @@ module AccessPermissions
|
|||
class ProjectsController < ApplicationController
|
||||
before_action :set_project
|
||||
before_action :check_read_permissions, only: %i(show)
|
||||
before_action :check_manage_permissions, only: %i(new create edit update destroy)
|
||||
before_action :check_manage_permissions, except: %i(show)
|
||||
|
||||
def new
|
||||
available_users = current_team.users.where.not(id: @project.users.pluck(:id))
|
||||
# automatically assigned or not assigned to project
|
||||
available_users = current_team.users.where(
|
||||
id: @project.user_assignments.automatically_assigned.select(:user_id)
|
||||
).or(
|
||||
current_team.users.where.not(id: @project.users.select(:id))
|
||||
)
|
||||
|
||||
@form = AccessPermissions::NewUserProjectForm.new(
|
||||
current_user,
|
||||
@project,
|
||||
|
@ -75,8 +81,17 @@ module AccessPermissions
|
|||
end
|
||||
end
|
||||
|
||||
def update_default_public_user_role
|
||||
@project.update!(permitted_default_public_user_role_params)
|
||||
UserAssignments::GroupAssignmentJob.perform_later(current_team, @project, current_user)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def permitted_default_public_user_role_params
|
||||
params.require(:project).permit(:default_public_user_role_id)
|
||||
end
|
||||
|
||||
def permitted_update_params
|
||||
params.require(:project_member)
|
||||
.permit(%i(user_role_id user_id))
|
||||
|
|
|
@ -44,7 +44,7 @@ module Api
|
|||
project_member = ProjectMember.new(user, @project, current_user)
|
||||
project_member.assign = true
|
||||
project_member.user_role_id = user_project_params[:user_role_id]
|
||||
project_member.create
|
||||
project_member.save
|
||||
|
||||
render jsonapi: project_member.user_assignment.reload,
|
||||
serializer: UserAssignmentSerializer,
|
||||
|
|
|
@ -20,7 +20,7 @@ module AccessPermissions
|
|||
if @error
|
||||
false
|
||||
else
|
||||
@resource_members.map(&:create)
|
||||
@resource_members.map(&:save)
|
||||
true
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,14 +9,19 @@ module UserAssignments
|
|||
@assigned_by = assigned_by
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
team.users.where.not(id: project.users.pluck(:id)).where.not(id: assigned_by.id).find_each do |user|
|
||||
UserAssignment.create!(
|
||||
team.users.where.not(id: assigned_by.id).find_each do |user|
|
||||
user_assignment = UserAssignment.find_or_initialize_by(
|
||||
user: user,
|
||||
assignable: project,
|
||||
user_role: project.default_public_user_role,
|
||||
assigned_by: @assigned_by,
|
||||
assigned: :automatically
|
||||
assignable: project
|
||||
)
|
||||
|
||||
next if user_assignment.manually_assigned?
|
||||
|
||||
user_assignment.update!(
|
||||
user_role: project.default_public_user_role,
|
||||
assigned_by: @assigned_by
|
||||
)
|
||||
|
||||
# make sure all related experiments and my modules are assigned
|
||||
UserAssignments::PropagateAssignmentJob.perform_later(
|
||||
project,
|
||||
|
|
|
@ -59,7 +59,20 @@ module UserAssignments
|
|||
# also destroy user designations if it's a MyModule
|
||||
object.user_my_modules.where(user: @user).destroy_all if object.is_a?(MyModule)
|
||||
|
||||
UserAssignment.where(user: @user, assignable: object).destroy_all
|
||||
user_assignment = UserAssignment.find_by!(user: @user, assignable: object)
|
||||
|
||||
if object.project.visible?
|
||||
# if project is public, the assignment
|
||||
# will reset to the default public role
|
||||
|
||||
user_assignment.update!(
|
||||
user_role_id: object.project.default_public_user_role_id,
|
||||
assigned: :automatically,
|
||||
assigned_by: @assigned_by
|
||||
)
|
||||
else
|
||||
user_assignment.destroy!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -36,6 +36,10 @@ module Assignable
|
|||
user_assignments.find_by(user: user)&.user_role
|
||||
end
|
||||
|
||||
def manually_assigned_users
|
||||
User.joins(:user_assignments).where(user_assignments: { assigned: :manually, assignable: self })
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_users_assignments
|
||||
|
|
|
@ -40,6 +40,7 @@ class MyModule < ApplicationRecord
|
|||
belongs_to :archived_by, foreign_key: 'archived_by_id', class_name: 'User', optional: true
|
||||
belongs_to :restored_by, foreign_key: 'restored_by_id', class_name: 'User', optional: true
|
||||
belongs_to :experiment, inverse_of: :my_modules, touch: true
|
||||
has_one :project, through: :experiment, autosave: false
|
||||
belongs_to :my_module_group, inverse_of: :my_modules, optional: true
|
||||
belongs_to :my_module_status, optional: true
|
||||
belongs_to :changing_from_my_module_status, optional: true, class_name: 'MyModuleStatus'
|
||||
|
|
|
@ -11,7 +11,6 @@ class ProjectMember
|
|||
validates :user, :project, presence: true, if: -> { assign }
|
||||
validates :user_role_id, presence: true, if: -> { assign }
|
||||
validate :validate_role_presence, if: -> { assign }
|
||||
validate :validate_user_assignment_presence, if: -> { assign }
|
||||
|
||||
def initialize(user, project, current_user = nil)
|
||||
@user = user
|
||||
|
@ -20,17 +19,21 @@ class ProjectMember
|
|||
@user_assignment = UserAssignment.find_by(assignable: @project, user: @user)
|
||||
end
|
||||
|
||||
def create
|
||||
def save
|
||||
return unless assign
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
@user_assignment = UserAssignment.create!(
|
||||
@user_assignment = UserAssignment.find_or_initialize_by(
|
||||
assignable: @project,
|
||||
user: @user,
|
||||
user: @user
|
||||
)
|
||||
|
||||
@user_assignment.update!(
|
||||
user_role_id: user_role_id,
|
||||
assigned_by: current_user,
|
||||
assigned: :manually
|
||||
)
|
||||
|
||||
log_activity(:assign_user_to_project)
|
||||
|
||||
UserAssignments::PropagateAssignmentJob.perform_later(
|
||||
|
@ -66,9 +69,17 @@ class ProjectMember
|
|||
return false if last_project_owner?
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
user_assignment.destroy!
|
||||
user_project&.destroy!
|
||||
log_activity(:unassign_user_from_project)
|
||||
# if project is public, the assignment
|
||||
# will reset to the default public role
|
||||
if @project.visible?
|
||||
user_assignment.update!(
|
||||
user_role: @project.default_public_user_role,
|
||||
assigned: :automatically
|
||||
)
|
||||
else
|
||||
user_assignment.destroy!
|
||||
user_project&.destroy!
|
||||
end
|
||||
|
||||
UserAssignments::PropagateAssignmentJob.perform_later(
|
||||
@project,
|
||||
|
@ -77,6 +88,8 @@ class ProjectMember
|
|||
current_user,
|
||||
destroy: true
|
||||
)
|
||||
|
||||
log_activity(:unassign_user_from_project)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -106,12 +119,6 @@ class ProjectMember
|
|||
errors.add(:user_role_id, :not_found) if UserRole.find_by(id: user_role_id).nil?
|
||||
end
|
||||
|
||||
def validate_user_assignment_presence
|
||||
return if UserAssignment.find_by(assignable: @project, user: @user).nil?
|
||||
|
||||
errors.add(:user_role_id, :already_present)
|
||||
end
|
||||
|
||||
def project_owners
|
||||
@project_owners ||= @project.user_assignments
|
||||
.includes(:user_role)
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<%= form_with(model: project, url: update_default_public_user_role_access_permissions_project_path(project), method: :put, remote: true, html: { class: 'row member-item', id: 'public_assignments', data: { action: 'replace-form autosave-form', object_type: :project } }) do |f| %>
|
||||
<div class="user-assignment-info">
|
||||
<div class="global-avatar-container">
|
||||
<%= image_tag "icon/team.png", class: 'img-circle pull-left' %>
|
||||
</div>
|
||||
<div>
|
||||
<%= t('access_permissions.everyone_else', team_name: f.object.team.name) %>
|
||||
<br>
|
||||
<small class="text-muted">
|
||||
<%= f.object.default_public_user_role.name %>
|
||||
<span class="permission-object-tag" title="<%= t("access_permissions.partials.project_tooltip") %>"">
|
||||
<%= t("access_permissions.partials.project") %>
|
||||
</span>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-assignment-controls">
|
||||
<div class="user-assignment-role">
|
||||
<%= f.select :default_public_user_role_id, options_for_select(user_roles_collection, selected: f.object.default_public_user_role_id), {}, class: 'form-control selectpicker', title: t('user_assignment.change_project_role'), data: { 'selected-text-format' => 'static' } %>
|
||||
</div>
|
||||
<div class="user-assignment-remove">
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
|
@ -6,10 +6,12 @@
|
|||
<h4 class="modal-title"><%= t '.title', resource_name: project.name %></h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<% project.users.each do |user| %>
|
||||
<%= render('access_permissions/partials/project_member_field.html.erb', user: user, project: project, update_path: update_path) %>
|
||||
<% project.manually_assigned_users.each do |user| %>
|
||||
<%= render('access_permissions/partials/project_member_field', user: user, project: project, update_path: update_path) %>
|
||||
<% end %>
|
||||
<%= render('access_permissions/partials/default_public_user_role_form', project: project) if project.visible? %>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<%= link_to new_resource_path, class: 'btn btn-default pull-left', data: { action: 'swap-remote-container', target: '#user_assignments_modal' } do %>
|
||||
<i class="fas fa-plus"></i>
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
json.form controller.render_to_string(
|
||||
partial: 'access_permissions/partials/default_public_user_role_form',
|
||||
formats: [:html],
|
||||
locals: {
|
||||
project: @project
|
||||
},
|
||||
layout: false
|
||||
)
|
|
@ -2527,6 +2527,7 @@ en:
|
|||
general_error: "Something went wrong"
|
||||
|
||||
access_permissions:
|
||||
everyone_else: "Everyone else at %{team_name}"
|
||||
create:
|
||||
success:
|
||||
one: "You have successfully granted access to %{count} member to the project."
|
||||
|
|
|
@ -261,6 +261,7 @@ Rails.application.routes.draw do
|
|||
|
||||
namespace :access_permissions do
|
||||
resources :projects, defaults: { format: 'json' } do
|
||||
put :update_default_public_user_role, on: :member
|
||||
resources :experiments, only: %i(show update edit) do
|
||||
resources :my_modules, only: %i(show update edit)
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue