Disallow duplicate channels - providers can define which fields should be ‘unique’

This commit is contained in:
David Taylor 2017-07-28 15:47:46 +01:00
parent 11c8817ebd
commit ce8acc9c26
9 changed files with 31 additions and 9 deletions

View File

@ -36,14 +36,28 @@ class DiscourseChat::Channel < DiscourseChat::PluginModel
return return
end end
check_unique = false
matching_channels = DiscourseChat::Channel.all
data.each do |key, value| data.each do |key, value|
regex_string = params.find{|p| p[:key] == key}[:regex] regex_string = params.find{|p| p[:key] == key}[:regex]
if !Regexp.new(regex_string).match?(value) if !Regexp.new(regex_string).match?(value)
errors.add(:data, "data.#{key} is invalid") errors.add(:data, "data.#{key} is invalid")
end end
unique = params.find{|p| p[:key] == key}[:unique]
if unique
check_unique = true
matching_channels = matching_channels.with_data_value(key, value)
end end
end end
if check_unique && matching_channels.exists?
errors.add(:data, "matches an existing channel")
end
end
def rules def rules
DiscourseChat::Rule.with_channel_id(id) DiscourseChat::Rule.with_channel_id(id)
end end

View File

@ -5,7 +5,7 @@ module DiscourseChat
PROVIDER_ENABLED_SETTING = :chat_integration_discord_enabled PROVIDER_ENABLED_SETTING = :chat_integration_discord_enabled
CHANNEL_PARAMETERS = [ CHANNEL_PARAMETERS = [
{key: "name", regex: '^\S+'}, {key: "name", regex: '^\S+'},
{key: "webhook_url", regex: '^https:\/\/discordapp\.com\/api\/webhooks\/', hidden: true} {key: "webhook_url", regex: '^https:\/\/discordapp\.com\/api\/webhooks\/', unique: true, hidden: true}
] ]
def self.send_message(url, message) def self.send_message(url, message)

View File

@ -5,7 +5,7 @@ module DiscourseChat
PROVIDER_ENABLED_SETTING = :chat_integration_hipchat_enabled PROVIDER_ENABLED_SETTING = :chat_integration_hipchat_enabled
CHANNEL_PARAMETERS = [ CHANNEL_PARAMETERS = [
{key: "name", regex: '^\S+'}, {key: "name", regex: '^\S+'},
{key: "webhook_url", regex: 'hipchat\.com', hidden:true}, {key: "webhook_url", regex: 'hipchat\.com', unique: true, hidden:true},
{key: "color", regex: '(yellow|green|red|purple|gray|random)'} {key: "color", regex: '(yellow|green|red|purple|gray|random)'}
] ]

View File

@ -5,7 +5,7 @@ module DiscourseChat
PROVIDER_ENABLED_SETTING = :chat_integration_matrix_enabled PROVIDER_ENABLED_SETTING = :chat_integration_matrix_enabled
CHANNEL_PARAMETERS = [ CHANNEL_PARAMETERS = [
{key: "name", regex: '^\S+'}, {key: "name", regex: '^\S+'},
{key: "room_id", regex: '^\!\S+:\S+$', hidden:true} {key: "room_id", regex: '^\!\S+:\S+$', unique: true, hidden:true}
] ]
def self.send_message(room_id, message) def self.send_message(room_id, message)

View File

@ -4,7 +4,7 @@ module DiscourseChat
PROVIDER_NAME = "mattermost".freeze PROVIDER_NAME = "mattermost".freeze
PROVIDER_ENABLED_SETTING = :chat_integration_mattermost_enabled PROVIDER_ENABLED_SETTING = :chat_integration_mattermost_enabled
CHANNEL_PARAMETERS = [ CHANNEL_PARAMETERS = [
{key: "identifier", regex: '^[@#]\S*$'} {key: "identifier", regex: '^[@#]\S*$', unique: true}
] ]
def self.send_via_webhook(message) def self.send_via_webhook(message)

View File

@ -4,7 +4,7 @@ module DiscourseChat::Provider::SlackProvider
PROVIDER_ENABLED_SETTING = :chat_integration_slack_enabled PROVIDER_ENABLED_SETTING = :chat_integration_slack_enabled
CHANNEL_PARAMETERS = [ CHANNEL_PARAMETERS = [
{key: "identifier", regex: '^[@#]\S*$'} {key: "identifier", regex: '^[@#]\S*$', unique: true}
] ]
def self.excerpt(post, max_length = SiteSetting.chat_integration_slack_excerpt_length) def self.excerpt(post, max_length = SiteSetting.chat_integration_slack_excerpt_length)

View File

@ -5,7 +5,7 @@ module DiscourseChat
PROVIDER_ENABLED_SETTING = :chat_integration_telegram_enabled PROVIDER_ENABLED_SETTING = :chat_integration_telegram_enabled
CHANNEL_PARAMETERS = [ CHANNEL_PARAMETERS = [
{key: "name", regex: '^\S+'}, {key: "name", regex: '^\S+'},
{key: "chat_id", regex: '^(-?[0-9]+|@\S+)$'} {key: "chat_id", regex: '^(-?[0-9]+|@\S+)$', unique: true}
] ]
def self.setup_webhook def self.setup_webhook

View File

@ -48,7 +48,7 @@ RSpec.shared_context "validated dummy provider" do
PROVIDER_NAME = "dummy2".freeze PROVIDER_NAME = "dummy2".freeze
PROVIDER_ENABLED_SETTING = :chat_integration_enabled # Tie to main plugin enabled setting PROVIDER_ENABLED_SETTING = :chat_integration_enabled # Tie to main plugin enabled setting
CHANNEL_PARAMETERS = [ CHANNEL_PARAMETERS = [
{key: "val", regex: '^\S+$'} {key: "val", regex: '^\S+$', unique: true}
] ]
@@sent_messages = [] @@sent_messages = []

View File

@ -24,7 +24,7 @@ RSpec.describe DiscourseChat::Channel do
it 'can be filtered by provider' do it 'can be filtered by provider' do
channel1 = DiscourseChat::Channel.create!(provider:'dummy') channel1 = DiscourseChat::Channel.create!(provider:'dummy')
channel2 = DiscourseChat::Channel.create!(provider:'dummy2', data:{val:"blah"}) channel2 = DiscourseChat::Channel.create!(provider:'dummy2', data:{val:"blah"})
channel3 = DiscourseChat::Channel.create!(provider:'dummy2', data:{val:"blah"}) channel3 = DiscourseChat::Channel.create!(provider:'dummy2', data:{val:"blah2"})
expect(DiscourseChat::Channel.all.length).to eq(3) expect(DiscourseChat::Channel.all.length).to eq(3)
@ -64,7 +64,6 @@ RSpec.describe DiscourseChat::Channel do
end end
describe 'validations' do describe 'validations' do
let(:channel) { }
it 'validates provider correctly' do it 'validates provider correctly' do
channel = DiscourseChat::Channel.create!(provider:"dummy") channel = DiscourseChat::Channel.create!(provider:"dummy")
@ -93,5 +92,14 @@ RSpec.describe DiscourseChat::Channel do
expect(channel2.valid?).to eq(false) expect(channel2.valid?).to eq(false)
end end
it 'disallows duplicate channels' do
channel1 = DiscourseChat::Channel.create(provider:"dummy2", data:{val:"hello"})
channel2 = DiscourseChat::Channel.new(provider:"dummy2", data:{val:"hello"})
expect(channel2.valid?).to eq(false)
channel2.data[:val] = "hello2"
expect(channel2.valid?).to eq(true)
end
end end
end end