mirror of
https://github.com/discourse/discourse.git
synced 2025-09-06 10:50:21 +08:00
FEATURE: add support for group members visibility level (#8004)
There are 5 visibility levels (similar to group visibility) public (default) logged-in users members only staff owners Admins & group owners always have visibility to group members.
This commit is contained in:
parent
f4aa6096ab
commit
88359b0f16
22 changed files with 351 additions and 15 deletions
|
@ -29,7 +29,7 @@ export default Ember.Controller.extend({
|
|||
this.set("loading", true);
|
||||
const model = this.model;
|
||||
|
||||
if (model) {
|
||||
if (model && model.can_see_members) {
|
||||
model.findMembers(this.memberParams).finally(() => {
|
||||
this.set(
|
||||
"application.showFooter",
|
||||
|
|
|
@ -162,6 +162,7 @@ const Group = RestModel.extend({
|
|||
mentionable_level: this.mentionable_level,
|
||||
messageable_level: this.messageable_level,
|
||||
visibility_level: this.visibility_level,
|
||||
members_visibility_level: this.members_visibility_level,
|
||||
automatic_membership_email_domains: this.emailDomains,
|
||||
automatic_membership_retroactive: !!this.automatic_membership_retroactive,
|
||||
title: this.title,
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
export default Ember.Route.extend({
|
||||
beforeModel: function() {
|
||||
this.transitionTo("group.activity.posts");
|
||||
beforeModel() {
|
||||
const group = this.modelFor("group");
|
||||
if (group.can_see_members) {
|
||||
this.transitionTo("group.activity.posts");
|
||||
} else {
|
||||
this.transitionTo("group.activity.mentions");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -14,6 +14,21 @@
|
|||
{{i18n 'admin.groups.manage.interaction.visibility_levels.description'}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label for="visiblity">{{i18n 'admin.groups.manage.interaction.members_visibility_levels.title'}}</label>
|
||||
|
||||
{{combo-box name="alias"
|
||||
valueAttribute="value"
|
||||
value=model.members_visibility_level
|
||||
content=visibilityLevelOptions
|
||||
castInteger=true
|
||||
class="groups-form-members-visibility-level"}}
|
||||
|
||||
<div class="control-instructions">
|
||||
{{i18n 'admin.groups.manage.interaction.members_visibility_levels.description'}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="control-group">
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
<section class="user-content">
|
||||
|
||||
<div class="group-members-actions">
|
||||
{{text-field value=filterInput
|
||||
placeholderKey=filterPlaceholder
|
||||
autocomplete="discourse"
|
||||
class="group-username-filter no-blur"}}
|
||||
{{#if model.can_see_members}}
|
||||
{{text-field value=filterInput
|
||||
placeholderKey=filterPlaceholder
|
||||
autocomplete="discourse"
|
||||
class="group-username-filter no-blur"}}
|
||||
{{/if}}
|
||||
|
||||
<div class="group-members-manage">
|
||||
{{#if canManageGroup}}
|
||||
|
@ -76,9 +78,13 @@
|
|||
{{/load-more}}
|
||||
|
||||
{{conditional-loading-spinner condition=loading}}
|
||||
{{else}}
|
||||
{{else if model.can_see_members}}
|
||||
<br>
|
||||
|
||||
<div>{{i18n "groups.empty.members"}}</div>
|
||||
{{else}}
|
||||
<br>
|
||||
|
||||
<div>{{i18n "groups.members.forbidden"}}</div>
|
||||
{{/if}}
|
||||
</section>
|
||||
</section>
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
<section class="user-secondary-navigation">
|
||||
{{#mobile-nav class='activity-nav' desktopClass='action-list activity-list nav-stacked' currentPath=router._router.currentPath}}
|
||||
{{group-activity-filter filter="posts" categoryId=category_id}}
|
||||
{{group-activity-filter filter="topics" categoryId=category_id}}
|
||||
{{#if model.can_see_members}}
|
||||
{{group-activity-filter filter="posts" categoryId=category_id}}
|
||||
{{group-activity-filter filter="topics" categoryId=category_id}}
|
||||
{{/if}}
|
||||
{{#if siteSettings.enable_mentions}}
|
||||
{{group-activity-filter filter="mentions" categoryId=category_id}}
|
||||
{{/if}}
|
||||
|
|
|
@ -135,6 +135,7 @@ class Admin::GroupsController < Admin::AdminController
|
|||
:mentionable_level,
|
||||
:messageable_level,
|
||||
:visibility_level,
|
||||
:members_visibility_level,
|
||||
:automatic_membership_email_domains,
|
||||
:automatic_membership_retroactive,
|
||||
:title,
|
||||
|
|
|
@ -159,6 +159,8 @@ class GroupsController < ApplicationController
|
|||
|
||||
def posts
|
||||
group = find_group(:group_id)
|
||||
guardian.ensure_can_see_group_members!(group)
|
||||
|
||||
posts = group.posts_for(
|
||||
guardian,
|
||||
params.permit(:before_post_id, :category_id)
|
||||
|
@ -168,6 +170,8 @@ class GroupsController < ApplicationController
|
|||
|
||||
def posts_feed
|
||||
group = find_group(:group_id)
|
||||
guardian.ensure_can_see_group_members!(group)
|
||||
|
||||
@posts = group.posts_for(
|
||||
guardian,
|
||||
params.permit(:before_post_id, :category_id)
|
||||
|
@ -204,6 +208,8 @@ class GroupsController < ApplicationController
|
|||
def members
|
||||
group = find_group(:group_id)
|
||||
|
||||
guardian.ensure_can_see_group_members!(group)
|
||||
|
||||
limit = (params[:limit] || 20).to_i
|
||||
offset = params[:offset].to_i
|
||||
|
||||
|
@ -542,6 +548,7 @@ class GroupsController < ApplicationController
|
|||
:incoming_email,
|
||||
:primary_group,
|
||||
:visibility_level,
|
||||
:members_visibility_level,
|
||||
:name,
|
||||
:grant_trust_level,
|
||||
:automatic_membership_email_domains,
|
||||
|
|
|
@ -161,6 +161,7 @@ class ListController < ApplicationController
|
|||
group = Group.find_by(name: params[:group_name])
|
||||
raise Discourse::NotFound unless group
|
||||
guardian.ensure_can_see_group!(group)
|
||||
guardian.ensure_can_see_group_members!(group)
|
||||
|
||||
list_opts = build_topic_list_options
|
||||
list = generate_list_for("group_topics", group, list_opts)
|
||||
|
|
|
@ -153,6 +153,59 @@ class Group < ActiveRecord::Base
|
|||
groups
|
||||
}
|
||||
|
||||
scope :members_visible_groups, Proc.new { |user, order, opts|
|
||||
groups = self.order(order || "name ASC")
|
||||
|
||||
if !opts || !opts[:include_everyone]
|
||||
groups = groups.where("groups.id > 0")
|
||||
end
|
||||
|
||||
unless user&.admin
|
||||
sql = <<~SQL
|
||||
groups.id IN (
|
||||
SELECT g.id FROM groups g WHERE g.members_visibility_level = :public
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT g.id FROM groups g
|
||||
WHERE g.members_visibility_level = :logged_on_users AND :user_id IS NOT NULL
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT g.id FROM groups g
|
||||
JOIN group_users gu ON gu.group_id = g.id AND
|
||||
gu.user_id = :user_id
|
||||
WHERE g.members_visibility_level = :members
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT g.id FROM groups g
|
||||
LEFT JOIN group_users gu ON gu.group_id = g.id AND
|
||||
gu.user_id = :user_id AND
|
||||
gu.owner
|
||||
WHERE g.members_visibility_level = :staff AND (gu.id IS NOT NULL OR :is_staff)
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT g.id FROM groups g
|
||||
JOIN group_users gu ON gu.group_id = g.id AND
|
||||
gu.user_id = :user_id AND
|
||||
gu.owner
|
||||
WHERE g.members_visibility_level = :owners
|
||||
|
||||
)
|
||||
SQL
|
||||
|
||||
groups = groups.where(
|
||||
sql,
|
||||
Group.visibility_levels.to_h.merge(user_id: user&.id, is_staff: !!user&.staff?)
|
||||
)
|
||||
|
||||
end
|
||||
|
||||
groups
|
||||
}
|
||||
|
||||
scope :mentionable, lambda { |user|
|
||||
where(self.mentionable_sql_clause,
|
||||
levels: alias_levels(user),
|
||||
|
@ -828,6 +881,7 @@ end
|
|||
# membership_request_template :text
|
||||
# messageable_level :integer default(0)
|
||||
# mentionable_level :integer default(0)
|
||||
# members_visibility_level :integer default(0), not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
|
|
@ -29,7 +29,9 @@ class BasicGroupSerializer < ApplicationSerializer
|
|||
:default_notification_level,
|
||||
:membership_request_template,
|
||||
:is_group_user,
|
||||
:is_group_owner
|
||||
:is_group_owner,
|
||||
:members_visibility_level,
|
||||
:can_see_members
|
||||
|
||||
def include_display_name?
|
||||
object.automatic
|
||||
|
@ -81,6 +83,10 @@ class BasicGroupSerializer < ApplicationSerializer
|
|||
owner_group_ids.include?(object.id)
|
||||
end
|
||||
|
||||
def can_see_members
|
||||
scope.can_see_group_members?(object)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def staff?
|
||||
|
|
|
@ -143,7 +143,7 @@ class UserSerializer < BasicUserSerializer
|
|||
|
||||
def groups
|
||||
object.groups.order(:id)
|
||||
.visible_groups(scope.user)
|
||||
.visible_groups(scope.user).members_visible_groups(scope.user)
|
||||
end
|
||||
|
||||
def group_users
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue