diff --git a/app/assets/javascripts/discourse/controllers/user_controller.js b/app/assets/javascripts/discourse/controllers/user_controller.js index 2b56d4bfa..4cbc4837f 100644 --- a/app/assets/javascripts/discourse/controllers/user_controller.js +++ b/app/assets/javascripts/discourse/controllers/user_controller.js @@ -13,7 +13,7 @@ Discourse.UserController = Discourse.ObjectController.extend({ }).property('content.username', 'Discourse.currentUser.username'), canSeePrivateMessages: (function() { - return this.get('viewingSelf') || Discourse.get('currentUser.moderator'); + return this.get('viewingSelf') || Discourse.get('currentUser.staff'); }).property('viewingSelf', 'Discourse.currentUser') }); diff --git a/app/assets/javascripts/discourse/templates/header.js.handlebars b/app/assets/javascripts/discourse/templates/header.js.handlebars index 6f0f7284a..4726c2743 100644 --- a/app/assets/javascripts/discourse/templates/header.js.handlebars +++ b/app/assets/javascripts/discourse/templates/header.js.handlebars @@ -65,26 +65,18 @@ <section class='d-dropdown' id='site-map-dropdown'> <ul> - {{#if Discourse.currentUser.moderator}} - <li><a href="/admin"><i class='icon-cog'></i>{{i18n admin_title}}</a></li> - <li><a href="/admin/flags/active"><i class='icon-flag'></i>{{i18n flags_title}}</a></li> + {{#if Discourse.currentUser.staff}} + <li><a href="/admin"><i class='icon icon-cog'></i>{{i18n admin_title}}</a></li> + <li><a href="/admin/flags/active"><i class='icon icon-flag'></i>{{i18n flags_title}}</a> + {{#if view.currentUser.site_flagged_posts_count}} + <a href='/admin/flags/active' title='{{i18n notifications.total_flagged}}' class='badge-notification flagged-posts'>{{view.currentUser.site_flagged_posts_count}}</a> + {{/if}} + </li> {{/if}} <li> {{#titledLinkTo "list.latest" titleKey="filters.latest.help"}}{{i18n filters.latest.title}}{{/titledLinkTo}} </li> <li>{{#linkTo 'faq'}}{{i18n faq}}{{/linkTo}}</li> - {{#if Discourse.currentUser.admin}} - <li title="{{i18n filters.favorited.help}}"> - {{#linkTo "list.favorited"}} - <i class='icon-star'></i>{{i18n filters.favorited.title}} - {{/linkTo}} - </li> - <li title="{{i18n filters.read.help}}"> - {{#linkTo "list.read"}} - <i class='icon-bookmark'></i>{{i18n filters.read.title}} - {{/linkTo}} - </li> - {{/if}} {{#if view.categories}} <li class='heading' title="{{i18n filters.categories.help}}"> {{#linkTo "list.categories"}}{{i18n filters.categories.title}}{{/linkTo}} diff --git a/app/assets/javascripts/discourse/templates/user/user.js.handlebars b/app/assets/javascripts/discourse/templates/user/user.js.handlebars index d74d70414..6ff78bba7 100644 --- a/app/assets/javascripts/discourse/templates/user/user.js.handlebars +++ b/app/assets/javascripts/discourse/templates/user/user.js.handlebars @@ -7,7 +7,7 @@ {{#if viewingSelf}} <button {{action "logout" target="Discourse"}} class='btn'>{{i18n user.log_out}}</button> {{/if}} - {{#if Discourse.currentUser.moderator}} + {{#if Discourse.currentUser.staff}} <a href="{{unbound content.adminPath}}" class='btn'><i class="icon-wrench"></i> {{i18n admin.user.show_admin_profile}}</a> {{/if}} <ul class="nav nav-pills"> diff --git a/app/assets/stylesheets/application/header.css.scss b/app/assets/stylesheets/application/header.css.scss index 499b287de..7adec65b7 100644 --- a/app/assets/stylesheets/application/header.css.scss +++ b/app/assets/stylesheets/application/header.css.scss @@ -129,9 +129,9 @@ left: -4px; background-color: #00953A; } - .flagged-posts { - background-color: #E53B2E; - } + } + .flagged-posts { + background-color: #E53B2E; } } @@ -170,6 +170,9 @@ padding: 5px; font-size: 13px; line-height: 16px; + .icon { + margin-right: 3px; + } } .heading { border-top: 1px solid #c5c5c5; diff --git a/app/controllers/admin/admin_controller.rb b/app/controllers/admin/admin_controller.rb index 622ae0af1..77d12479c 100644 --- a/app/controllers/admin/admin_controller.rb +++ b/app/controllers/admin/admin_controller.rb @@ -1,7 +1,7 @@ class Admin::AdminController < ApplicationController before_filter :ensure_logged_in - before_filter :ensure_is_moderator + before_filter :ensure_staff def index render nothing: true @@ -9,8 +9,9 @@ class Admin::AdminController < ApplicationController protected - def ensure_is_moderator - raise Discourse::InvalidAccess.new unless current_user.moderator? - end + # this is not really necessary cause the routes are secure + def ensure_staff + raise Discourse::InvalidAccess.new unless current_user.staff? + end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 1f0dced37..4377e8a4a 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -38,6 +38,10 @@ module ApplicationHelper current_user.try(:moderator?) end + def staff? + current_user.try(:staff?) + end + # Creates open graph and twitter card meta data def crawlable_meta_data(opts=nil) diff --git a/app/models/post_action.rb b/app/models/post_action.rb index 4b2f27737..789d33c0f 100644 --- a/app/models/post_action.rb +++ b/app/models/post_action.rb @@ -25,7 +25,7 @@ class PostAction < ActiveRecord::Base 'topics.deleted_at' => nil).count('DISTINCT posts.id') $redis.set('posts_flagged_count', posts_flagged_count) - user_ids = User.where("admin = 't' or moderator = 't'").select(:id).map {|u| u.id} + user_ids = User.staff.select(:id).map {|u| u.id} MessageBus.publish('/flagged_counts', { total: posts_flagged_count }, { user_ids: user_ids }) end diff --git a/app/models/user.rb b/app/models/user.rb index e8f12a8d2..e590937fd 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -54,6 +54,7 @@ class User < ActiveRecord::Base scope :admins, ->{ where(admin: true) } scope :moderators, ->{ where(moderator: true) } + scope :staff, ->{ where("moderator = 't' or admin = 't'") } module NewTopicDuration ALWAYS = -1 @@ -267,10 +268,8 @@ class User < ActiveRecord::Base User.select(:username).order('last_posted_at desc').limit(20) end - def moderator? - # this saves us from checking both, admins are always moderators - # - # in future we may split this out + # any user that is either a moderator or an admin + def staff? admin || moderator end diff --git a/app/models/user_action.rb b/app/models/user_action.rb index 8c4cdcc8d..20299bf79 100644 --- a/app/models/user_action.rb +++ b/app/models/user_action.rb @@ -190,7 +190,7 @@ LEFT JOIN categories c on c.id = t.category_id builder.where("t.archetype != :archetype", archetype: Archetype::private_message) end - unless guardian.is_moderator? + unless guardian.is_staff? allowed = guardian.secure_category_ids if allowed.present? builder.where("( c.secure IS NULL OR diff --git a/app/serializers/current_user_serializer.rb b/app/serializers/current_user_serializer.rb index 45f0ef9c1..2f0c3be79 100644 --- a/app/serializers/current_user_serializer.rb +++ b/app/serializers/current_user_serializer.rb @@ -7,6 +7,7 @@ class CurrentUserSerializer < BasicUserSerializer :notification_channel_position, :site_flagged_posts_count, :moderator?, + :staff?, :reply_count, :topic_count, :enable_quoting, @@ -15,15 +16,8 @@ class CurrentUserSerializer < BasicUserSerializer # we probably want to move this into site, but that json is cached so hanging it off current user seems okish - def moderator - # TODO we probably want better terminology - # - # we have admins / moderators and users who are either moderators or admins denoted by moderator? - object.moderator? - end - def include_site_flagged_posts_count? - object.moderator? + object.staff? end def topic_count @@ -34,10 +28,6 @@ class CurrentUserSerializer < BasicUserSerializer object.posts.where("post_number > 1").count end - def moderator? - object.moderator? - end - def site_flagged_posts_count PostAction.flagged_posts_count end diff --git a/app/serializers/post_serializer.rb b/app/serializers/post_serializer.rb index 18f581adb..1c9efb377 100755 --- a/app/serializers/post_serializer.rb +++ b/app/serializers/post_serializer.rb @@ -88,7 +88,7 @@ class PostSerializer < ApplicationSerializer end def cooked - if object.hidden && !scope.is_moderator? + if object.hidden && !scope.is_staff? if scope.current_user && object.user_id == scope.current_user.id I18n.t('flagging.you_must_edit') else @@ -154,7 +154,7 @@ class PostSerializer < ApplicationSerializer # The following only applies if you're logged in if action_summary[:can_act] && scope.current_user.present? - action_summary[:can_clear_flags] = scope.is_moderator? && PostActionType.flag_types.values.include?(id) + action_summary[:can_clear_flags] = scope.is_staff? && PostActionType.flag_types.values.include?(id) end if post_actions.present? && post_actions.has_key?(id) @@ -163,7 +163,7 @@ class PostSerializer < ApplicationSerializer end # anonymize flags - if !scope.is_moderator? && PostActionType.flag_types.values.include?(id) + if !scope.is_staff? && PostActionType.flag_types.values.include?(id) action_summary[:count] = action_summary[:acted] ? 1 : 0 end diff --git a/app/views/common/_discourse_javascript.html.erb b/app/views/common/_discourse_javascript.html.erb index 883d4c6cd..e4b4f4d87 100644 --- a/app/views/common/_discourse_javascript.html.erb +++ b/app/views/common/_discourse_javascript.html.erb @@ -18,7 +18,7 @@ <%# load the selected locale before any other scripts %> <%= javascript_include_tag "locales/#{I18n.locale}" %> <%= javascript_include_tag "application" %> -<%- if moderator? %> +<%- if staff? %> <%= javascript_include_tag "admin"%> <%- end %> diff --git a/app/views/common/_discourse_stylesheet.html.erb b/app/views/common/_discourse_stylesheet.html.erb index cca9c1ebe..3c8b93a4e 100644 --- a/app/views/common/_discourse_stylesheet.html.erb +++ b/app/views/common/_discourse_stylesheet.html.erb @@ -2,7 +2,7 @@ <%=stylesheet_link_tag "application"%> <%- end %> -<%- if moderator? %> +<%- if staff? %> <%= stylesheet_link_tag "admin"%> <%-end%> <%=SiteCustomization.custom_stylesheet(session[:preview_style])%> diff --git a/config/routes.rb b/config/routes.rb index 181cdeb4a..c384557c1 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,7 +1,7 @@ require 'sidekiq/web' require_dependency 'admin_constraint' -require_dependency 'moderator_constraint' +require_dependency 'staff_constraint' require_dependency 'homepage_constraint' # This used to be User#username_format, but that causes a preload of the User object @@ -22,7 +22,7 @@ Discourse::Application.routes.draw do end get 'srv/status' => 'forums#status' - namespace :admin, constraints: ModeratorConstraint.new do + namespace :admin, constraints: StaffConstraint.new do get '' => 'admin#index' resources :site_settings, constraints: AdminConstraint.new diff --git a/lib/guardian.rb b/lib/guardian.rb index 7679a6b2d..4488b395a 100644 --- a/lib/guardian.rb +++ b/lib/guardian.rb @@ -15,8 +15,8 @@ class Guardian @user && @user.admin? end - def is_moderator? - @user && @user.moderator? + def is_staff? + @user && @user.staff? end # Can the user see the object? @@ -54,7 +54,7 @@ class Guardian def can_moderate?(obj) return false if obj.blank? return false if @user.blank? - @user.moderator? + @user.staff? end alias :can_move_posts? :can_moderate? alias :can_see_flags? :can_moderate? @@ -103,7 +103,7 @@ class Guardian return false if target.blank? return false if @user.blank? return false if target.approved? - @user.moderator? + @user.staff? end def can_ban?(user) @@ -116,7 +116,7 @@ class Guardian def can_clear_flags?(post) return false if @user.blank? return false if post.blank? - @user.moderator? + @user.staff? end def can_revoke_admin?(admin) @@ -136,32 +136,30 @@ class Guardian end def can_revoke_moderation?(moderator) - return false unless @user.try(:admin?) + return false unless is_admin? return false if moderator.blank? return false if @user.id == moderator.id - return false unless moderator.moderator? true end def can_grant_moderation?(user) - return false unless @user.try(:admin?) + return false unless is_admin? return false if user.blank? return false if @user.id == user.id - return false if user.admin? - return false if user.moderator? + return false if user.staff? true end def can_delete_user?(user_to_delete) - return false unless @user.try(:admin?) - return false if user_to_delete.blank? + return false unless is_admin? + return false unless user_to_delete return false if user_to_delete.post_count > 0 true end # Can we see who acted on a post in a particular way? def can_see_post_actors?(topic, post_action_type_id) - return false unless topic.present? + return false unless topic type_symbol = PostActionType.types[post_action_type_id] return false if type_symbol == :bookmark @@ -178,37 +176,36 @@ class Guardian # Support sites that have to approve users def can_access_forum? return true unless SiteSetting.must_approve_users? - return false if user.blank? + return false unless @user - # Admins can't lock themselves out of a site - return true if user.admin? + # Staff can't lock themselves out of a site + return true if is_staff? - user.approved? + @user.approved? end def can_see_pending_invites_from?(user) - return false if user.blank? - return false if @user.blank? + return false unless user && @user return user == @user end # For now, can_invite_to is basically can_see? def can_invite_to?(object) - return false if @user.blank? + return false unless @user return false unless can_see?(object) return false if SiteSetting.must_approve_users? - @user.has_trust_level?(:regular) || @user.moderator? + @user.has_trust_level?(:regular) || @user.staff? end def can_see_deleted_posts? - return true if is_admin? + return true if is_staff? false end def can_see_private_messages?(user_id) - return true if is_moderator? - return false if @user.blank? + return true if is_staff? + return false unless @user @user.id == user_id end @@ -240,11 +237,11 @@ class Guardian # Creating Methods def can_create_category?(parent) - @user.moderator? + is_staff? end def can_create_post_on_topic?(topic) - return true if @user.moderator? + return true if is_staff? return false if topic.closed? return false if topic.archived? true @@ -252,22 +249,22 @@ class Guardian # Editing Methods def can_edit_category?(category) - @user.moderator? + is_staff? end def can_edit_post?(post) - return true if @user.moderator? + return true if is_staff? return false if post.topic.archived? (post.user == @user) end def can_edit_user?(user) return true if user == @user - @user.moderator? + is_staff? end def can_edit_topic?(topic) - return true if @user.moderator? + return true if is_staff? return true if topic.user == @user false end @@ -280,22 +277,22 @@ class Guardian # You can delete your own posts return !post.user_deleted? if post.user == @user - @user.moderator? + is_staff? end # Recovery Method def can_recover_post?(post) - return false if @user.blank? - @user.moderator? + return false unless @user + is_staff? end def can_delete_category?(category) - return false unless @user.moderator? + return false unless is_staff? return category.topic_count == 0 end def can_delete_topic?(topic) - return false unless @user.moderator? + return false unless is_staff? return false if Category.exists?(topic_id: topic.id) true end @@ -313,7 +310,7 @@ class Guardian def can_send_private_message?(target) return false unless User === target || Group === target - return false if @user.blank? + return false unless @user # Can't send message to yourself return false if User === target && @user.id == target.id @@ -325,8 +322,8 @@ class Guardian end def can_reply_as_new_topic?(topic) - return false if @user.blank? - return false if topic.blank? + return false unless @user + return false unless topic return false if topic.private_message? @user.has_trust_level?(:basic) @@ -335,7 +332,7 @@ class Guardian def can_see_topic?(topic) return false unless topic - return true if @user && @user.moderator? + return true if @user && is_staff? return false if topic.deleted_at if topic.category && topic.category.secure @@ -353,7 +350,7 @@ class Guardian def can_see_post?(post) return false unless post - return true if @user && @user.moderator? + return true if @user && is_staff? return false if post.deleted_at.present? can_see_topic?(post.topic) diff --git a/lib/rate_limiter.rb b/lib/rate_limiter.rb index a8df33218..3c027294e 100644 --- a/lib/rate_limiter.rb +++ b/lib/rate_limiter.rb @@ -22,7 +22,7 @@ class RateLimiter def can_perform? return true if RateLimiter.disabled? - return true if @user.moderator? + return true if @user.staff? result = $redis.get(@key) return true if result.blank? @@ -32,7 +32,7 @@ class RateLimiter def performed! return if RateLimiter.disabled? - return if @user.moderator? + return if @user.staff? result = $redis.incr(@key).to_i $redis.expire(@key, @secs) if result == 1 diff --git a/lib/moderator_constraint.rb b/lib/staff_constraint.rb similarity index 90% rename from lib/moderator_constraint.rb rename to lib/staff_constraint.rb index 86edbc056..95ec8287b 100644 --- a/lib/moderator_constraint.rb +++ b/lib/staff_constraint.rb @@ -1,6 +1,6 @@ require_dependency 'current_user' -class ModeratorConstraint +class StaffConstraint def matches?(request) return false unless request.session[:current_user_id].present? diff --git a/lib/topic_view.rb b/lib/topic_view.rb index b5f01fd58..bcd89d9c8 100644 --- a/lib/topic_view.rb +++ b/lib/topic_view.rb @@ -23,7 +23,7 @@ class TopicView @limit = options[:limit] || SiteSetting.posts_per_page; @filtered_posts = @topic.posts - @filtered_posts = @filtered_posts.with_deleted if user.try(:admin?) + @filtered_posts = @filtered_posts.with_deleted if user.try(:staff?) @filtered_posts = @filtered_posts.best_of if options[:best_of].present? if options[:username_filters].present? @@ -299,7 +299,7 @@ class TopicView .includes(:user) .includes(:reply_to_user) .order('sort_order') - @posts = @posts.with_deleted if @user.try(:admin?) + @posts = @posts.with_deleted if @user.try(:staff?) @posts end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index b4b6dfcfb..b83513ff5 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -311,9 +311,9 @@ describe User do user.has_trust_level?(:elder).should be_true end - it "is a moderator if the user is an admin" do + it "is staff if the user is an admin" do user.admin = true - user.moderator?.should be_true + user.staff?.should be_true end end