scinote-web/app/models/project_member.rb
artoscinote 78ab094bf2
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]
2021-12-01 16:23:24 +01:00

128 lines
3.3 KiB
Ruby

# frozen_string_literal: true
class ProjectMember
include ActiveModel::Model
attr_accessor :user, :project, :assign, :user_role_id, :user_id
attr_reader :current_user, :user_assignment, :user_role, :user_project
delegate :user_role, to: :user_assignment, allow_nil: true
validates :user, :project, presence: true, if: -> { assign }
validates :user_role_id, presence: true, if: -> { assign }
validate :validate_role_presence, if: -> { assign }
def initialize(user, project, current_user = nil)
@user = user
@project = project
@current_user = current_user
@user_assignment = UserAssignment.find_by(assignable: @project, user: @user)
end
def save
return unless assign
ActiveRecord::Base.transaction do
@user_assignment = UserAssignment.find_or_initialize_by(
assignable: @project,
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(
@project,
@user,
user_role,
current_user
)
end
end
def update
validate_role_presence
return false unless valid?
ActiveRecord::Base.transaction do
@user_assignment = UserAssignment.find_by!(assignable: @project, user: @user)
@user_assignment.update!(user_role_id: user_role_id, assigned: :manually)
log_activity(:change_user_role_on_project)
UserAssignments::PropagateAssignmentJob.perform_later(
@project,
@user,
user_role,
current_user
)
end
end
def destroy
user_assignment = UserAssignment.find_by!(assignable: @project, user: @user)
user_project = UserProject.find_by(project: @project, user: @user)
return false if last_project_owner?
ActiveRecord::Base.transaction do
# 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,
@user,
user_role,
current_user,
destroy: true
)
log_activity(:unassign_user_from_project)
end
end
def assign=(value)
@assign = ActiveModel::Type::Boolean.new.cast(value)
end
def last_project_owner?
project_owners.count == 1 && user_role.owner?
end
private
def log_activity(type_of)
Activities::CreateActivityService
.call(activity_type: type_of,
owner: current_user,
subject: project,
team: project.team,
project: project,
message_items: { project: project.id,
user_target: user.id,
role: user_role.name })
end
def validate_role_presence
errors.add(:user_role_id, :not_found) if UserRole.find_by(id: user_role_id).nil?
end
def project_owners
@project_owners ||= @project.user_assignments
.includes(:user_role)
.where(user_roles: { name: I18n.t('user_roles.predefined.owner') })
end
end