2
0
Fork 0
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:
Vinoth Kannan 2019-08-14 19:00:04 +05:30 committed by GitHub
parent f4aa6096ab
commit 88359b0f16
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 351 additions and 15 deletions

View file

@ -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",

View file

@ -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,

View file

@ -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");
}
}
});

View file

@ -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">

View file

@ -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>

View file

@ -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}}

View file

@ -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,

View file

@ -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,

View file

@ -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)

View file

@ -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
#

View file

@ -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?

View file

@ -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