FEATURE: Warn if invited user cannot see topic (#13548)

Users can invite people to topics from secured category, but they will
not be redirected to the topic after signing up unless they have the
permissions to view the topic. This commit shows a warning when invite
is saved if the topic is in a secured category and none of the invite
groups are allowed to see it.
This commit is contained in:
Dan Ungureanu 2021-07-06 12:49:26 +03:00 committed by GitHub
parent f999ef2d52
commit 34387c5a38
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 67 additions and 7 deletions

View File

@ -62,7 +62,12 @@ export default Component.extend({
const modalAlert = document.getElementById("modal-alert");
if (modalAlert) {
modalAlert.style.display = "none";
modalAlert.classList.remove("alert-info", "alert-error", "alert-success");
modalAlert.classList.remove(
"alert-error",
"alert-info",
"alert-success",
"alert-warning"
);
}
},

View File

@ -99,10 +99,15 @@ export default Controller.extend(
return this.invite
.save(data)
.then(() => {
.then((result) => {
this.rollbackBuffer();
this.setAutogenerated(opts.autogenerated);
if (!this.autogenerated) {
if (result.warnings) {
this.appEvents.trigger("modal-body:flash", {
text: result.warnings.join(","),
messageClass: "warning",
});
} else if (!this.autogenerated) {
if (this.isEmail && opts.sendEmail) {
this.send("closeModal");
} else {

View File

@ -102,7 +102,7 @@ class InvitesController < ApplicationController
)
if invite.present?
render_serialized(invite, InviteSerializer, scope: guardian, root: nil, show_emails: params.has_key?(:email))
render_serialized(invite, InviteSerializer, scope: guardian, root: nil, show_emails: params.has_key?(:email), show_warnings: true)
else
render json: failed_json, status: 422
end
@ -121,7 +121,7 @@ class InvitesController < ApplicationController
guardian.ensure_can_invite_to_forum!(nil)
render_serialized(invite, InviteSerializer, scope: guardian, root: nil, show_emails: params.has_key?(:email))
render_serialized(invite, InviteSerializer, scope: guardian, root: nil, show_emails: params.has_key?(:email), show_warnings: true)
end
def update
@ -194,7 +194,7 @@ class InvitesController < ApplicationController
Jobs.enqueue(:invite_email, invite_id: invite.id, invite_to_topic: params[:invite_to_topic])
end
render_serialized(invite, InviteSerializer, scope: guardian, root: nil, show_emails: params.has_key?(:email))
render_serialized(invite, InviteSerializer, scope: guardian, root: nil, show_emails: params.has_key?(:email), show_warnings: true)
end
def destroy

View File

@ -249,6 +249,23 @@ class Invite < ActiveRecord::Base
Jobs.enqueue(:invite_email, invite_id: self.id)
end
def warnings(guardian)
@warnings ||= begin
warnings = []
topic = self.topics.first
if topic&.read_restricted_category?
topic_groups = topic.category.groups
if (self.groups & topic_groups).blank?
editable_topic_groups = topic_groups.filter { |g| guardian.can_edit_group?(g) }
warnings << I18n.t("invite.requires_groups", groups: editable_topic_groups.pluck(:name).join(", "))
end
end
warnings
end
end
def limit_invites_per_day
RateLimiter.new(invited_by, "invites-per-day", SiteSetting.max_invites_per_day, 1.day.to_i)
end

View File

@ -12,7 +12,8 @@ class InviteSerializer < ApplicationSerializer
:created_at,
:updated_at,
:expires_at,
:expired
:expired,
:warnings
has_many :topics, embed: :object, serializer: BasicTopicSerializer
has_many :groups, embed: :object, serializer: BasicGroupSerializer
@ -44,4 +45,12 @@ class InviteSerializer < ApplicationSerializer
def expired
object.expired?
end
def warnings
object.warnings(scope)
end
def include_warnings?
object.warnings(scope).present?
end
end

View File

@ -254,6 +254,7 @@ en:
disabled_errors:
discourse_connect_enabled: "Invites are disabled because DiscourseConnect is enabled."
invalid_access: "You are not permitted to view the requested resource."
requires_groups: "Invite saved. To give access to the specified topic, add one of the following groups: %{groups}."
bulk_invite:
file_should_be_csv: "The uploaded file should be of csv format."

View File

@ -404,4 +404,27 @@ describe Invite do
expect(invite.invalidated_at).to be_nil
end
end
describe '#warnings' do
fab!(:admin) { Fabricate(:admin) }
fab!(:invite) { Fabricate(:invite) }
fab!(:group) { Fabricate(:group) }
fab!(:secured_category) do
secured_category = Fabricate(:category)
secured_category.permissions = { group.name => :full }
secured_category.save!
secured_category
end
it 'does not return any warnings for simple invites' do
expect(invite.warnings(admin.guardian)).to be_blank
end
it 'returns a warning if topic is private' do
topic = Fabricate(:topic, category: secured_category)
TopicInvite.create!(topic: topic, invite: invite)
expect(invite.warnings(admin.guardian)).to contain_exactly(I18n.t("invite.requires_groups", groups: group.name))
end
end
end