mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-10 23:25:31 +08:00
200 lines
7.6 KiB
Ruby
200 lines
7.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module AccessPermissions
|
|
class BaseController < ApplicationController
|
|
include InputSanitizeHelper
|
|
include UserRolesHelper
|
|
|
|
before_action :set_model
|
|
before_action :set_assignment, only: %i(create update destroy)
|
|
before_action :check_read_permissions, only: %i(show show_user_group_assignments user_roles)
|
|
before_action :check_manage_permissions, except: %i(show show_user_group_assignments user_roles)
|
|
before_action :load_available_users, only: %i(new create)
|
|
|
|
def show
|
|
render json: @model.user_assignments.where(team: current_team).includes(:user_role, :user).order('users.full_name ASC'),
|
|
each_serializer: UserAssignmentSerializer, user: current_user
|
|
end
|
|
|
|
def new
|
|
render json: @available_users, each_serializer: UserSerializer, user: current_user
|
|
end
|
|
|
|
def edit; end
|
|
|
|
def create
|
|
ActiveRecord::Base.transaction do
|
|
@assignment.update!(
|
|
user_role_id: permitted_params[:user_role_id],
|
|
assigned_by: current_user,
|
|
assigned: :manually
|
|
)
|
|
|
|
case assignment_type
|
|
when :team
|
|
log_activity(:"#{model_parameter}_access_granted_all_team_members", team: @assignment.team.id, role: @assignment.user_role.name)
|
|
when :user
|
|
log_activity(:"#{model_parameter}_access_granted", user_target: @assignment.user.id, role: @assignment.user_role.name)
|
|
when :user_group
|
|
log_activity(:"#{model_parameter}_access_granted_user_group", user_group: @assignment.user_group.id, role: @assignment.user_role.name)
|
|
end
|
|
|
|
propagate_job
|
|
|
|
@message = if assignment_type == :team
|
|
t('access_permissions.create.success', member_name: t('access_permissions.all_team'))
|
|
else
|
|
t('access_permissions.create.success', member_name: escape_input(assignment_type == :user_group ? @assignment.user_group.name : @assignment.user.name))
|
|
end
|
|
render json: { message: @message }
|
|
rescue ActiveRecord::RecordInvalid => e
|
|
Rails.logger.error e.message
|
|
errors = @model.errors.present? ? @model.errors&.map(&:message)&.join(',') : e.message
|
|
render json: { flash: errors }, status: :unprocessable_entity
|
|
raise ActiveRecord::Rollback
|
|
end
|
|
end
|
|
|
|
def update
|
|
# prevent role change if it would result in no manually assigned users having the user management permission
|
|
new_user_role = UserRole.find(permitted_params[:user_role_id])
|
|
if permitted_params[:user_id].present? && permitted_params[:user_id] != 'all' && !new_user_role.has_permission?(manage_permission_constant) &&
|
|
@assignment.last_with_permission?(manage_permission_constant, assigned: :manually)
|
|
raise ActiveRecord::RecordInvalid
|
|
end
|
|
|
|
@assignment.update!(user_role_id: permitted_params[:user_role_id], assigned_by: current_user)
|
|
|
|
case assignment_type
|
|
when :team
|
|
log_activity(:"#{model_parameter}_access_changed_all_team_members", team: @assignment.team.id, role: @assignment.user_role.name)
|
|
when :user
|
|
log_activity(:"#{model_parameter}_access_changed", user_target: @assignment.user.id, role: @assignment.user_role.name)
|
|
when :user_group
|
|
log_activity(:"#{model_parameter}_access_changed_user_group", user_group: @assignment.user_group.id, role: @assignment.user_role.name)
|
|
end
|
|
|
|
propagate_job
|
|
|
|
render json: { user_role_id: @assignment.user_role_id }, status: :ok
|
|
rescue ActiveRecord::RecordInvalid
|
|
render json: { flash: t('access_permissions.update.failure') }, status: :unprocessable_entity
|
|
end
|
|
|
|
def destroy
|
|
# prevent deletion of last manually assigned user that can manage users
|
|
if params[:user_id].present? && params[:user_id] != 'all' && @assignment.last_with_permission?(manage_permission_constant, assigned: :manually)
|
|
raise ActiveRecord::RecordInvalid
|
|
end
|
|
|
|
UserAssignments::PropagateAssignmentJob.perform_now(@assignment, destroy: true)
|
|
|
|
case assignment_type
|
|
when :team
|
|
@assigned_name = @assignment.team.name
|
|
log_activity(:"#{model_parameter}_access_revoked_all_team_members", team: @assignment.team.id, role: @assignment.user_role.name)
|
|
when :user_group
|
|
@assigned_name = @assignment.user_group.name
|
|
log_activity(:"#{model_parameter}_access_revoked_user_group", user_group: @assignment.user_group.id, role: @assignment.user_role.name)
|
|
when :user
|
|
@assigned_name = @assignment.user.full_name
|
|
log_activity(:"#{model_parameter}_access_revoked", user_target: @assignment.user.id, role: @assignment.user_role.name)
|
|
end
|
|
|
|
render json: { message: t('access_permissions.destroy.success', member_name: escape_input(@assigned_name)) }
|
|
rescue ActiveRecord::RecordInvalid
|
|
render json: { message: t('access_permissions.destroy.failure') },
|
|
status: :unprocessable_entity
|
|
end
|
|
|
|
def show_user_group_assignments
|
|
render json: @model.user_group_assignments.where(team: current_team).includes(:user_role, :user_group).order('user_groups.name ASC'),
|
|
each_serializer: UserGroupAssignmentSerializer, user: current_user
|
|
end
|
|
|
|
def unassigned_user_groups
|
|
render json: current_team.user_groups.where.not(id: @model.user_group_assignments.select(:user_group_id)),
|
|
each_serializer: UserGroupSerializer, user: current_user
|
|
end
|
|
|
|
def user_roles
|
|
render json: { data: user_roles_collection(@model).map(&:reverse) }
|
|
end
|
|
|
|
private
|
|
|
|
def model_parameter
|
|
@model.class.permission_class.model_name.param_key
|
|
end
|
|
|
|
def manage_permission_constant
|
|
"#{@model.class.permission_class.name}Permissions::USERS_MANAGE".constantize
|
|
end
|
|
|
|
def permitted_default_public_user_role_params
|
|
params.require(:object).permit(:default_public_user_role_id)
|
|
end
|
|
|
|
def permitted_params
|
|
params.require(:user_assignment)
|
|
.permit(%i(user_role_id user_id user_group_id team_id))
|
|
end
|
|
|
|
def load_available_users
|
|
@available_users = current_team.users.where.not(id: @model.user_assignments.where(team: current_team).select(:user_id)).order(users: { full_name: :asc })
|
|
end
|
|
|
|
def propagate_job(destroy: false)
|
|
return unless @model.has_permission_children?
|
|
|
|
UserAssignments::PropagateAssignmentJob.perform_later(
|
|
@assignment,
|
|
destroy: destroy
|
|
)
|
|
end
|
|
|
|
def check_manage_permissions
|
|
raise NotImplementedError
|
|
end
|
|
|
|
def check_read_permissions
|
|
raise NotImplementedError
|
|
end
|
|
|
|
def log_activity(type_of, message_items = {})
|
|
message_items = { model_parameter => @model.id }.merge(message_items)
|
|
|
|
Activities::CreateActivityService
|
|
.call(activity_type: type_of,
|
|
owner: current_user,
|
|
subject: @model,
|
|
team: @model.team,
|
|
project: @project,
|
|
message_items: message_items)
|
|
end
|
|
|
|
def set_assignment
|
|
case assignment_type
|
|
when :user, :user_group
|
|
@assignment = @model.public_send(:"#{assignment_type}_assignments").find_or_initialize_by(
|
|
"#{assignment_type}_id": permitted_params[:"#{assignment_type}_id"],
|
|
team: current_team
|
|
)
|
|
when :team
|
|
@assignment =
|
|
@model.team_assignments
|
|
.find_or_initialize_by(team: current_team, assignable: @model)
|
|
end
|
|
end
|
|
|
|
def assignment_type
|
|
if permitted_params[:team_id].present? || permitted_params[:user_id] == 'all'
|
|
:team
|
|
elsif permitted_params[:user_group_id].present?
|
|
:user_group
|
|
elsif permitted_params[:user_id].present?
|
|
:user
|
|
end
|
|
end
|
|
end
|
|
end
|