Allow providers to specify a regex that the channel identifier is checked against during validation

This commit is contained in:
David Taylor 2017-07-04 00:14:01 +01:00
parent 444e380ca1
commit 4be010fd07
10 changed files with 77 additions and 20 deletions

View File

@ -9,13 +9,15 @@ export default Ember.Controller.extend({
modalShowing: false,
actions:{
create(provider){
create(){
this.set('modalShowing', true);
showModal('admin-plugins-chat-edit-rule', { model: this.store.createRecord('rule',{provider: provider}), admin: true });
var model = {rule: this.store.createRecord('rule',{provider: this.get('model.provider').id}), provider:this.get('model.provider')};
showModal('admin-plugins-chat-edit-rule', { model: model, admin: true });
},
edit(rule){
this.set('modalShowing', true);
showModal('admin-plugins-chat-edit-rule', { model: rule, admin: true });
var model = {rule: rule, provider:this.get('model.provider')};
showModal('admin-plugins-chat-edit-rule', { model: model, admin: true });
},
delete(rule){
const self = this;

View File

@ -2,11 +2,45 @@ import Rule from 'discourse/plugins/discourse-chat-integration/admin/models/rule
import ModalFunctionality from 'discourse/mixins/modal-functionality';
import { ajax } from 'discourse/lib/ajax';
import { extractError } from 'discourse/lib/ajax-error';
import InputValidation from 'discourse/models/input-validation';
export default Ember.Controller.extend(ModalFunctionality, {
model: Rule.create({}),
channelValidation: function(){
var regString = this.get('model.provider.channel_regex');
var regex = new RegExp(regString);
var val = this.get('model.rule.channel');
if(val == ""){ // Fail silently if field blank
return InputValidation.create({
failed: true,
});
}else if(!regString){ // Pass silently if no regex available for provider
return InputValidation.create({
ok: true,
});
}else if(regex.test(val)){ // Test against regex
return InputValidation.create({
ok: true,
reason: I18n.t('chat_integration.edit_rule_modal.channel_validation.ok')
});
}else{ // Failed regex
return InputValidation.create({
failed: true,
reason: I18n.t('chat_integration.edit_rule_modal.channel_validation.fail')
});
}
}.property('model.rule.channel'),
saveDisabled: function(){
if(this.get('channelValidation.failed')){ return true }
return false;
}.property('channelValidation.failed'),
actions: {
cancel: function(){
this.send('closeModal');
@ -16,7 +50,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
const self = this;
this.get('model').update().then(function(result) {
this.get('model.rule').update().then(function(result) {
self.send('closeModal');
}).catch(function(error) {
self.flash(extractError(error), 'error');

View File

@ -6,12 +6,12 @@ export default Discourse.Route.extend({
model(params, transition) {
return Ember.RSVP.hash({
rules: this.store.find('rule', {provider: params.provider}),
provider: params.provider
provider: this.modelFor("admin-plugins-chat").findBy('id',params.provider)
});
},
serialize: function(model, params) {
return { provider: model['provider']};
return { provider: model['provider'].get('id')};
},
actions: {

View File

@ -1,7 +1,7 @@
import AdminPluginsChatProvider from 'discourse/plugins/discourse-chat-integration/admin/routes/admin-plugins-chat-provider'
export default Discourse.Route.extend({
model(params, transition) {
model(params, transition) {
return this.store.findAll('provider');
},

View File

@ -6,7 +6,7 @@
<tr class="input">
<td class="label"><label for='provider'>{{i18n "chat_integration.edit_rule_modal.provider"}}</label></td>
<td>
{{i18n (concat 'chat_integration.provider.' model.provider '.title')}}
{{i18n (concat 'chat_integration.provider.' model.rule.provider '.title')}}
</td>
</tr>
<tr class="instructions">
@ -19,20 +19,22 @@
<td>
{{text-field
name="channel"
value=model.channel
value=model.rule.channel
autofocus="autofocus"
id="channel-field"}}
&nbsp;{{input-tip validation=channelValidation}}
</td>
</tr>
<tr class="instructions">
<td></td>
<td><label>{{i18n (concat 'chat_integration.provider.' model.provider '.channel_instructions')}}</label></td>
<td><label>{{i18n (concat 'chat_integration.provider.' model.rule.provider '.channel_instructions')}}</label></td>
</tr>
<tr class="input">
<td class="label"><label for='filter'>{{i18n "chat_integration.edit_rule_modal.filter"}}</label></td>
<td>
{{combo-box name="filter" content=model.available_filters value=model.filter}}
{{combo-box name="filter" content=model.rule.available_filters value=model.rule.filter}}
</td>
</tr>
<tr class="instructions">
@ -45,7 +47,7 @@
<td>
{{category-chooser
name="category"
value=model.category_id
value=model.rule.category_id
rootNoneLabel="chat_integration.all_categories"
rootNone=true
overrideWidths=false
@ -61,7 +63,7 @@
<tr class="input">
<td class="label"><label for='tags'>{{i18n "chat_integration.edit_rule_modal.tags"}}</label></td>
<td>
{{tag-chooser placeholderKey="chat_integration.all_tags" name="tags" tags=model.tags}}
{{tag-chooser placeholderKey="chat_integration.all_tags" name="tags" tags=model.rule.tags}}
</td>
</tr>
<tr class="instructions">
@ -77,7 +79,8 @@
{{/d-modal-body}}
<div class="modal-footer">
{{d-button class='btn-primary btn-large' action="save" title="chat_integration.edit_rule_modal.save" label="chat_integration.edit_rule_modal.save"}}
{{d-button class='btn-primary btn-large' action="save" title="chat_integration.edit_rule_modal.save" label="chat_integration.edit_rule_modal.save" disabled=saveDisabled}}
{{d-button class="btn-large" action="cancel" title="chat_integration.edit_rule_modal.cancel" label="chat_integration.edit_rule_modal.cancel"}}

View File

@ -27,6 +27,9 @@ en:
tags: "Tags"
channel: "Channel"
filter: "Filter"
channel_validation:
ok: "Valid"
fail: "Invalid channel format"
instructions:
filter: "Notification level. Mute overrides other matching rules."
category: "This rule will only apply to topics in the specified category."

View File

@ -5,6 +5,8 @@ module DiscourseChat::Provider::SlackProvider
PROVIDER_ENABLED_SETTING = :chat_integration_slack_enabled
PROVIDER_CHANNEL_REGEX = '^[@#]\S*$'
def self.excerpt(post, max_length = SiteSetting.chat_integration_slack_excerpt_length)
doc = Nokogiri::HTML.fragment(post.excerpt(max_length,
remap_emoji: true,

View File

@ -22,7 +22,7 @@
end
def category_id=(val)
if val.nil? or val.empty?
if val.nil? or val.blank?
@category_id = nil
else
@category_id = val.to_i
@ -102,6 +102,12 @@
# Validate channel
return false if @channel.blank?
provider = ::DiscourseChat::Provider.get_by_name(@provider)
if defined? provider::PROVIDER_CHANNEL_REGEX
channel_regex = Regexp.new provider::PROVIDER_CHANNEL_REGEX
return false if not channel_regex.match?(@channel)
end
# Validate category
return false if not (@category_id.nil? or Category.where(id: @category_id).exists?)

View File

@ -69,7 +69,12 @@ after_initialize do
end
def list_providers
providers = ::DiscourseChat::Provider.enabled_providers.map {|x| {name: x::PROVIDER_NAME, id: x::PROVIDER_NAME}}
providers = ::DiscourseChat::Provider.enabled_providers.map {|x| {
name: x::PROVIDER_NAME,
id: x::PROVIDER_NAME,
channel_regex: (defined? x::PROVIDER_CHANNEL_REGEX) ? x::PROVIDER_CHANNEL_REGEX : nil
}}
render json:providers, root: 'providers'
end
@ -85,7 +90,7 @@ after_initialize do
end
filter_order = ["watch", "follow", "mute"]
rules = rules.sort_by{ |r| [r.channel, filter_order.index(r.filter), r.category_id] }
rules = rules.sort_by{ |r| [r.channel, r.category_id.nil? ? 0 : r.category_id, filter_order.index(r.filter)] }
render_serialized rules, DiscourseChat::RuleSerializer, root: 'rules'
end

View File

@ -82,7 +82,7 @@ RSpec.describe DiscourseChat::Rule do
it 'can be filtered by provider' do
rule2 = DiscourseChat::Rule.new({provider:'telegram', channel:'blah'}).save!
rule3 = DiscourseChat::Rule.new({provider:'slack', channel:'blah'}).save!
rule3 = DiscourseChat::Rule.new({provider:'slack', channel:'#blah'}).save!
expect(DiscourseChat::Rule.all.length).to eq(3)
@ -91,8 +91,8 @@ RSpec.describe DiscourseChat::Rule do
end
it 'can be filtered by category' do
rule2 = DiscourseChat::Rule.new({provider:'slack', channel:'blah', category_id: 1}).save!
rule3 = DiscourseChat::Rule.new({provider:'slack', channel:'blah', category_id: nil}).save!
rule2 = DiscourseChat::Rule.new({provider:'slack', channel:'#blah', category_id: 1}).save!
rule3 = DiscourseChat::Rule.new({provider:'slack', channel:'#blah', category_id: nil}).save!
expect(DiscourseChat::Rule.all.length).to eq(3)
@ -122,6 +122,8 @@ RSpec.describe DiscourseChat::Rule do
expect(rule.valid?).to eq(true)
rule.channel = ''
expect(rule.valid?).to eq(false)
rule.channel = 'blah'
expect(rule.valid?).to eq(false)
end
it 'validates category correctly' do