Revision d51d3c9b
Added by Timo Goebel over 6 years ago
app/models/host/base.rb | ||
---|---|---|
scope :no_organization, -> { rewhere(:organization_id => nil) }
|
||
|
||
delegate :ssh_authorized_keys, :to => :owner, :allow_nil => true
|
||
delegate :notification_recipients_ids, :to => :owner, :allow_nil => true
|
||
|
||
PRIMARY_INTERFACE_ATTRIBUTES = [:name, :ip, :ip6, :mac,
|
||
:subnet, :subnet_id, :subnet_name,
|
app/models/notification.rb | ||
---|---|---|
# This class' responsibility is, given a notification blueprint, to determine
|
||
# who are the notification recipients
|
||
class Notification < ApplicationRecord
|
||
AUDIENCE_USER = 'user'
|
||
AUDIENCE_GROUP = 'usergroup'
|
||
AUDIENCE_TAXONOMY = 'taxonomy'
|
||
AUDIENCE_GLOBAL = 'global'
|
||
AUDIENCE_ADMIN = 'admin'
|
||
AUDIENCE_USER = 'user'
|
||
AUDIENCE_USERGROUP = 'usergroup'
|
||
AUDIENCE_GLOBAL = 'global'
|
||
AUDIENCE_ADMIN = 'admin'
|
||
# calls notification_recipients_ids on the subject to
|
||
# determine the recipient user ids
|
||
AUDIENCE_SUBJECT = 'subject'
|
||
|
||
belongs_to :notification_blueprint
|
||
belongs_to :initiator, :class_name => User, :foreign_key => 'user_id'
|
||
... | ... | |
validates :notification_blueprint, :presence => true
|
||
validates :initiator, :presence => true
|
||
validates :audience, :inclusion => {
|
||
:in => [AUDIENCE_USER, AUDIENCE_GROUP, AUDIENCE_TAXONOMY,
|
||
:in => [AUDIENCE_USER, AUDIENCE_USERGROUP, AUDIENCE_SUBJECT,
|
||
AUDIENCE_GLOBAL, AUDIENCE_ADMIN]
|
||
}, :presence => true
|
||
validates :message, :presence => true
|
||
... | ... | |
case audience
|
||
when AUDIENCE_GLOBAL
|
||
User.reorder('').pluck(:id)
|
||
when AUDIENCE_TAXONOMY
|
||
subject.user_ids.uniq
|
||
when AUDIENCE_USER
|
||
[initiator.id]
|
||
when AUDIENCE_ADMIN
|
||
User.unscoped.only_admin.except_hidden.reorder('').uniq.pluck(:id)
|
||
when AUDIENCE_GROUP
|
||
subject.all_users.uniq.map(&:id) # This needs to be rewritten in usergroups.
|
||
else
|
||
subject.try(:notification_recipients_ids) || []
|
||
end
|
||
end
|
||
|
app/models/taxonomy.rb | ||
---|---|---|
(self.send("#{type.downcase}_parameters".to_sym).authorized(:view_params) + taxonomy_inherited_params_objects.to_a.reverse!).uniq {|param| param.name}
|
||
end
|
||
|
||
def notification_recipients_ids
|
||
self.subtree.flat_map(&:users).map(&:id).uniq
|
||
end
|
||
|
||
private
|
||
|
||
delegate :need_to_be_selected_ids, :selected_ids, :used_and_selected_ids, :mismatches, :missing_ids, :check_for_orphans,
|
app/models/user.rb | ||
---|---|---|
{ login => super }
|
||
end
|
||
|
||
def notification_recipients_ids
|
||
[self.id]
|
||
end
|
||
|
||
private
|
||
|
||
def prepare_password
|
app/models/usergroup.rb | ||
---|---|---|
all_users.flat_map(&:ssh_keys)
|
||
end
|
||
|
||
def notification_recipients_ids
|
||
all_users.map(&:id)
|
||
end
|
||
|
||
protected
|
||
|
||
# Recurses down the tree of usergroups and finds the users
|
app/services/ui_notifications.rb | ||
---|---|---|
# Do not break actions using notifications even if there is a failure.
|
||
logger.warn("Failed to handle notifications - this is most likely a bug: #{e}")
|
||
logger.debug(e.backtrace.join("\n"))
|
||
false
|
||
end
|
||
|
||
def self.logger
|
app/services/ui_notifications/hosts.rb | ||
---|---|---|
module Hosts
|
||
class Base < UINotifications::Base
|
||
def deliver!
|
||
if audience.nil? || initiator.nil?
|
||
unless subject.owner
|
||
logger.warn("Invalid owner for #{subject}, unable to send notifications")
|
||
# add notification for missing owner
|
||
UINotifications::Hosts::MissingOwner.deliver!(subject)
|
||
... | ... | |
protected
|
||
|
||
def audience
|
||
case subject.owner_type
|
||
when 'User'
|
||
::Notification::AUDIENCE_USER
|
||
when 'Usergroup'
|
||
::Notification::AUDIENCE_GROUP
|
||
end
|
||
::Notification::AUDIENCE_SUBJECT if subject.owner
|
||
end
|
||
|
||
def initiator
|
app/services/ui_notifications/hosts/destroy.rb | ||
---|---|---|
Notification.create!(
|
||
initiator: initiator,
|
||
audience: audience,
|
||
# note we do not store the subject, as the object is being deleted.
|
||
subject: subject.owner, # note we store the host owner, as the host object is being deleted.
|
||
message: StringParser.new(blueprint.message, {subject: subject}),
|
||
notification_blueprint: blueprint
|
||
)
|
||
end
|
||
|
||
def audience
|
||
case subject.owner_type
|
||
when 'User'
|
||
::Notification::AUDIENCE_USER
|
||
when 'Usergroup'
|
||
::Notification::AUDIENCE_USERGROUP
|
||
end
|
||
end
|
||
|
||
def delete_others
|
||
logger.debug("Removing all notifications for host: #{subject}")
|
||
Notification.where(subject: subject).destroy_all
|
test/models/notification_test.rb | ||
---|---|---|
end
|
||
|
||
test 'user notifications should subscribe only to itself' do
|
||
notification = FactoryGirl.build(:notification,
|
||
:audience => Notification::AUDIENCE_USER)
|
||
assert_equal [notification.initiator.id], notification.subscriber_ids
|
||
notification = FactoryGirl.create(:notification,
|
||
:subject => User.current,
|
||
:audience => Notification::AUDIENCE_USER)
|
||
assert_equal [User.current.id], notification.subscriber_ids
|
||
end
|
||
|
||
test 'usergroup notifications should subscribe to all of its members' do
|
||
group = FactoryGirl.create(:usergroup)
|
||
group.users = FactoryGirl.create_list(:user,25)
|
||
notification = FactoryGirl.build(:notification,
|
||
:audience => Notification::AUDIENCE_GROUP)
|
||
:audience => Notification::AUDIENCE_USERGROUP)
|
||
notification.subject = group
|
||
assert group.all_users.any?
|
||
assert_equal group.all_users.map(&:id),
|
||
notification.subscriber_ids
|
||
assert_equal group.all_users.map(&:id).sort,
|
||
notification.subscriber_ids.sort
|
||
end
|
||
|
||
test 'Organization notifications should subscribe to all of its members' do
|
||
org = FactoryGirl.create(:organization)
|
||
org.users = FactoryGirl.create_list(:user,25)
|
||
notification = FactoryGirl.build(:notification,
|
||
:audience => Notification::AUDIENCE_TAXONOMY)
|
||
:audience => Notification::AUDIENCE_SUBJECT)
|
||
notification.subject = org
|
||
assert org.user_ids.any?
|
||
assert_equal org.user_ids, notification.subscriber_ids
|
||
assert_equal org.user_ids.sort, notification.subscriber_ids.sort
|
||
end
|
||
|
||
test 'Location notifications should subscribe to all of its members' do
|
||
loc = FactoryGirl.create(:location)
|
||
loc.users = FactoryGirl.create_list(:user,25)
|
||
notification = FactoryGirl.build(:notification,
|
||
:audience => Notification::AUDIENCE_TAXONOMY)
|
||
:audience => Notification::AUDIENCE_SUBJECT)
|
||
notification.subject = loc
|
||
assert loc.user_ids.any?
|
||
assert_equal loc.user_ids, notification.subscriber_ids
|
||
assert_equal loc.user_ids.sort, notification.subscriber_ids.sort
|
||
end
|
||
|
||
test 'Global notifications should subscribe to all users' do
|
||
notification = FactoryGirl.build(:notification,
|
||
:audience => Notification::AUDIENCE_GLOBAL)
|
||
assert User.count > 0
|
||
assert_equal User.reorder('').pluck(:id),
|
||
notification.subscriber_ids
|
||
assert_equal User.reorder('').pluck(:id).sort,
|
||
notification.subscriber_ids.sort
|
||
end
|
||
|
||
test 'Admin notifications should subscribe to all admin users except hidden' do
|
test/unit/ui_notifications/hosts/base_test.rb | ||
---|---|---|
require 'test_helper'
|
||
|
||
class UINotificationsHostsTest < ActiveSupport::TestCase
|
||
test 'notification audience should be user' do
|
||
host.owner = FactoryGirl.build(:user)
|
||
assert_equal 'user', audience
|
||
class TestNotification < ::UINotifications::Hosts::Base
|
||
def create
|
||
::Notification.create!(
|
||
initiator: initiator,
|
||
subject: subject,
|
||
audience: audience,
|
||
notification_blueprint: blueprint
|
||
)
|
||
end
|
||
|
||
def blueprint
|
||
@blueprint ||= FactoryGirl.create(:notification_blueprint)
|
||
end
|
||
end
|
||
|
||
test 'notification audience should be usergroup' do
|
||
host.owner = FactoryGirl.build(:usergroup)
|
||
assert_equal 'usergroup', audience
|
||
test 'notification audience should be SUBJECT if owner is present' do
|
||
host.owner = FactoryGirl.build(:user)
|
||
assert_equal 'subject', audience
|
||
end
|
||
|
||
test 'notification audience should be nil if there is no owner' do
|
||
... | ... | |
assert !base.deliver!
|
||
end
|
||
|
||
describe 'deliver notification to host owner' do
|
||
test 'owner is single user' do
|
||
host.owner = FactoryGirl.create(:user)
|
||
assert_difference("NotificationRecipient.all.count", 1) do
|
||
assert TestNotification.new(host).deliver!
|
||
end
|
||
end
|
||
|
||
test 'owner is usergroup' do
|
||
group = FactoryGirl.create(:usergroup)
|
||
group.users = FactoryGirl.create_list(:user, 5)
|
||
host.owner = group
|
||
assert_difference("NotificationRecipient.all.count", 5) do
|
||
assert TestNotification.new(host).deliver!
|
||
end
|
||
end
|
||
end
|
||
|
||
private
|
||
|
||
def host
|
Also available in: Unified diff
fixes #20653 - ui notifications for hosts with usergroup owner