diff --git a/app/assets/javascripts/discourse/components/d-editor.js.es6 b/app/assets/javascripts/discourse/components/d-editor.js.es6 index 010f11bd2ba..f5c30f3b522 100644 --- a/app/assets/javascripts/discourse/components/d-editor.js.es6 +++ b/app/assets/javascripts/discourse/components/d-editor.js.es6 @@ -45,7 +45,8 @@ const isInside = (text, regex) => { class Toolbar { - constructor(site) { + constructor(opts) { + const { site, siteSettings } = opts; this.shortcuts = {}; this.groups = [ @@ -74,7 +75,14 @@ class Toolbar { perform: e => e.applySurround('_', '_', 'italic_text') }); - this.addButton({id: 'link', group: 'insertions', shortcut: 'K', action: 'showLinkModal'}); + if (opts.showLink) { + this.addButton({ + id: 'link', + group: 'insertions', + shortcut: 'K', + action: 'showLinkModal' + }); + } this.addButton({ id: 'quote', @@ -108,7 +116,7 @@ class Toolbar { perform: e => e.applyList(i => !i ? "1. " : `${parseInt(i) + 1}. `, 'list_item') }); - if (Discourse.SiteSettings.support_mixed_text_direction) { + if (siteSettings.support_mixed_text_direction) { this.addButton({ id: 'toggle-direction', group: 'extras', @@ -200,6 +208,7 @@ export default Ember.Component.extend({ lastSel: null, _mouseTrap: null, emojiPickerIsActive: false, + showLink: true, @computed('placeholder') placeholderTranslated(placeholder) { @@ -279,7 +288,9 @@ export default Ember.Component.extend({ @computed toolbar() { - const toolbar = new Toolbar(this.site); + const toolbar = new Toolbar( + this.getProperties('site', 'siteSettings', 'showLink') + ); _createCallbacks.forEach(cb => cb(toolbar)); this.sendAction('extraButtons', toolbar); return toolbar; diff --git a/app/assets/javascripts/discourse/templates/components/composer-editor.hbs b/app/assets/javascripts/discourse/templates/components/composer-editor.hbs index 037ee5440ff..511961d8f14 100644 --- a/app/assets/javascripts/discourse/templates/components/composer-editor.hbs +++ b/app/assets/javascripts/discourse/templates/components/composer-editor.hbs @@ -11,6 +11,7 @@ validation=validation loading=composer.loading forcePreview=forcePreview + showLink=currentUser.can_post_link composerEvents=true onExpandPopupMenuOptions="onExpandPopupMenuOptions" onPopupMenuAction=onPopupMenuAction diff --git a/app/serializers/current_user_serializer.rb b/app/serializers/current_user_serializer.rb index 46fa8fe05ce..b96d7f28b32 100644 --- a/app/serializers/current_user_serializer.rb +++ b/app/serializers/current_user_serializer.rb @@ -39,7 +39,12 @@ class CurrentUserSerializer < BasicUserSerializer :seen_notification_id, :primary_group_id, :primary_group_name, - :can_create_topic + :can_create_topic, + :can_post_link + + def can_post_link + scope.can_post_link? + end def can_create_topic scope.can_create_topic?(nil) diff --git a/lib/guardian/post_guardian.rb b/lib/guardian/post_guardian.rb index 6986d1099ec..39f207b597b 100644 --- a/lib/guardian/post_guardian.rb +++ b/lib/guardian/post_guardian.rb @@ -1,6 +1,11 @@ #mixin for all guardian methods dealing with post permissions module PostGuardian + def can_post_link? + authenticated? && + @user.has_trust_level?(TrustLevel[SiteSetting.min_trust_to_post_links]) + end + # Can the user act on the post in a particular way. # taken_actions = the list of actions the user has already taken def post_can_act?(post, action_key, opts: {}, can_see_post: nil) diff --git a/lib/validators/post_validator.rb b/lib/validators/post_validator.rb index 40ec3fdee28..37caff0053e 100644 --- a/lib/validators/post_validator.rb +++ b/lib/validators/post_validator.rb @@ -93,7 +93,9 @@ class Validators::PostValidator < ActiveModel::Validator end def can_post_links_validator(post) - return if post.link_count == 0 || acting_user_is_trusted?(post, SiteSetting.min_trust_to_post_links) || private_message?(post) + return if post.link_count == 0 || + Guardian.new(post.acting_user).can_post_link? || + private_message?(post) post.errors.add(:base, I18n.t(:links_require_trust)) end diff --git a/spec/components/guardian_spec.rb b/spec/components/guardian_spec.rb index 5ec7904b355..d61502367f4 100644 --- a/spec/components/guardian_spec.rb +++ b/spec/components/guardian_spec.rb @@ -26,6 +26,24 @@ describe Guardian do expect { Guardian.new(user) }.not_to raise_error end + describe "can_post_link?" do + it "returns false for anonymous users" do + expect(Guardian.new.can_post_link?).to eq(false) + end + + it "returns true for a regular user" do + expect(Guardian.new(user).can_post_link?).to eq(true) + end + + it "supports customization by site setting" do + user.trust_level = 0 + SiteSetting.min_trust_to_post_links = 0 + expect(Guardian.new(user).can_post_link?).to eq(true) + SiteSetting.min_trust_to_post_links = 1 + expect(Guardian.new(user).can_post_link?).to eq(false) + end + end + describe 'post_can_act?' do let(:post) { build(:post) } let(:user) { build(:user) }