Screened URLs list in admin
This commit is contained in:
parent
def134605d
commit
293361dcd3
|
@ -0,0 +1,21 @@
|
||||||
|
/**
|
||||||
|
This controller supports the interface for listing screened URLs in the admin section.
|
||||||
|
|
||||||
|
@class AdminLogsScreenedUrlsController
|
||||||
|
@extends Ember.ArrayController
|
||||||
|
@namespace Discourse
|
||||||
|
@module Discourse
|
||||||
|
**/
|
||||||
|
Discourse.AdminLogsScreenedUrlsController = Ember.ArrayController.extend(Discourse.Presence, {
|
||||||
|
loading: false,
|
||||||
|
content: [],
|
||||||
|
|
||||||
|
show: function() {
|
||||||
|
var self = this;
|
||||||
|
this.set('loading', true);
|
||||||
|
Discourse.ScreenedUrl.findAll().then(function(result) {
|
||||||
|
self.set('content', result);
|
||||||
|
self.set('loading', false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
|
@ -9,7 +9,7 @@
|
||||||
**/
|
**/
|
||||||
Discourse.ScreenedEmail = Discourse.Model.extend({
|
Discourse.ScreenedEmail = Discourse.Model.extend({
|
||||||
actionName: function() {
|
actionName: function() {
|
||||||
return I18n.t("admin.logs.screened_emails.actions." + this.get('action'));
|
return I18n.t("admin.logs.screened_actions." + this.get('action'));
|
||||||
}.property('action')
|
}.property('action')
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
/**
|
||||||
|
Represents a URL that is watched for, and an action may be taken.
|
||||||
|
|
||||||
|
@class ScreenedUrl
|
||||||
|
@extends Discourse.Model
|
||||||
|
@namespace Discourse
|
||||||
|
@module Discourse
|
||||||
|
**/
|
||||||
|
Discourse.ScreenedUrl = Discourse.Model.extend({
|
||||||
|
actionName: function() {
|
||||||
|
return I18n.t("admin.logs.screened_actions." + this.get('action'));
|
||||||
|
}.property('action')
|
||||||
|
});
|
||||||
|
|
||||||
|
Discourse.ScreenedUrl.reopenClass({
|
||||||
|
findAll: function(filter) {
|
||||||
|
return Discourse.ajax("/admin/logs/screened_urls.json").then(function(screened_urls) {
|
||||||
|
return screened_urls.map(function(b) {
|
||||||
|
return Discourse.ScreenedUrl.create(b);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
|
@ -12,24 +12,6 @@ Discourse.AdminLogsIndexRoute = Discourse.Route.extend({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
The route that lists blocked email addresses.
|
|
||||||
|
|
||||||
@class AdminLogsScreenedEmailsRoute
|
|
||||||
@extends Discourse.Route
|
|
||||||
@namespace Discourse
|
|
||||||
@module Discourse
|
|
||||||
**/
|
|
||||||
Discourse.AdminLogsScreenedEmailsRoute = Discourse.Route.extend({
|
|
||||||
renderTemplate: function() {
|
|
||||||
this.render('admin/templates/logs/screened_emails', {into: 'adminLogs'});
|
|
||||||
},
|
|
||||||
|
|
||||||
setupController: function() {
|
|
||||||
return this.controllerFor('adminLogsScreenedEmails').show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The route that lists staff actions that were logged.
|
The route that lists staff actions that were logged.
|
||||||
|
|
||||||
|
@ -57,4 +39,40 @@ Discourse.AdminLogsStaffActionLogsRoute = Discourse.Route.extend({
|
||||||
// Clear any filters when we leave the route
|
// Clear any filters when we leave the route
|
||||||
Discourse.URL.set('queryParams', null);
|
Discourse.URL.set('queryParams', null);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
The route that lists blocked email addresses.
|
||||||
|
|
||||||
|
@class AdminLogsScreenedEmailsRoute
|
||||||
|
@extends Discourse.Route
|
||||||
|
@namespace Discourse
|
||||||
|
@module Discourse
|
||||||
|
**/
|
||||||
|
Discourse.AdminLogsScreenedEmailsRoute = Discourse.Route.extend({
|
||||||
|
renderTemplate: function() {
|
||||||
|
this.render('admin/templates/logs/screened_emails', {into: 'adminLogs'});
|
||||||
|
},
|
||||||
|
|
||||||
|
setupController: function() {
|
||||||
|
return this.controllerFor('adminLogsScreenedEmails').show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
The route that lists screened URLs.
|
||||||
|
|
||||||
|
@class AdminLogsScreenedUrlsRoute
|
||||||
|
@extends Discourse.Route
|
||||||
|
@namespace Discourse
|
||||||
|
@module Discourse
|
||||||
|
**/
|
||||||
|
Discourse.AdminLogsScreenedUrlsRoute = Discourse.Route.extend({
|
||||||
|
renderTemplate: function() {
|
||||||
|
this.render('admin/templates/logs/screened_urls', {into: 'adminLogs'});
|
||||||
|
},
|
||||||
|
|
||||||
|
setupController: function() {
|
||||||
|
return this.controllerFor('adminLogsScreenedUrls').show();
|
||||||
|
}
|
||||||
});
|
});
|
|
@ -30,8 +30,9 @@ Discourse.Route.buildRoutes(function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.resource('adminLogs', { path: '/logs' }, function() {
|
this.resource('adminLogs', { path: '/logs' }, function() {
|
||||||
this.route('screenedEmails', { path: '/screened_emails' });
|
|
||||||
this.route('staffActionLogs', { path: '/staff_action_logs' });
|
this.route('staffActionLogs', { path: '/staff_action_logs' });
|
||||||
|
this.route('screenedEmails', { path: '/screened_emails' });
|
||||||
|
this.route('screenedUrls', { path: '/screened_urls' });
|
||||||
});
|
});
|
||||||
|
|
||||||
this.route('groups', {path: '/groups'});
|
this.route('groups', {path: '/groups'});
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
<ul class="nav nav-pills">
|
<ul class="nav nav-pills">
|
||||||
<li>{{#linkTo 'adminLogs.staffActionLogs'}}{{i18n admin.logs.staff_actions.title}}{{/linkTo}}</li>
|
<li>{{#linkTo 'adminLogs.staffActionLogs'}}{{i18n admin.logs.staff_actions.title}}{{/linkTo}}</li>
|
||||||
<li>{{#linkTo 'adminLogs.screenedEmails'}}{{i18n admin.logs.screened_emails.title}}{{/linkTo}}</li>
|
<li>{{#linkTo 'adminLogs.screenedEmails'}}{{i18n admin.logs.screened_emails.title}}{{/linkTo}}</li>
|
||||||
|
<li>{{#linkTo 'adminLogs.screenedUrls'}}{{i18n admin.logs.screened_urls.title}}{{/linkTo}}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,12 +5,12 @@
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if model.length}}
|
{{#if model.length}}
|
||||||
|
|
||||||
<div class='table blocked-emails'>
|
<div class='table screened-emails'>
|
||||||
<div class="heading-container">
|
<div class="heading-container">
|
||||||
<div class="col heading first email">{{i18n admin.logs.screened_emails.email}}</div>
|
<div class="col heading first email">{{i18n admin.logs.screened_emails.email}}</div>
|
||||||
<div class="col heading action">{{i18n admin.logs.action}}</div>
|
<div class="col heading action">{{i18n admin.logs.action}}</div>
|
||||||
<div class="col heading match_count">{{i18n admin.logs.screened_emails.match_count}}</div>
|
<div class="col heading match_count">{{i18n admin.logs.match_count}}</div>
|
||||||
<div class="col heading last_match_at">{{i18n admin.logs.screened_emails.last_match_at}}</div>
|
<div class="col heading last_match_at">{{i18n admin.logs.last_match_at}}</div>
|
||||||
<div class="col heading created_at">{{i18n admin.logs.created_at}}</div>
|
<div class="col heading created_at">{{i18n admin.logs.created_at}}</div>
|
||||||
<div class="clearfix"></div>
|
<div class="clearfix"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
<p>{{i18n admin.logs.screened_urls.description}}</p>
|
||||||
|
|
||||||
|
{{#if loading}}
|
||||||
|
<div class='admin-loading'>{{i18n loading}}</div>
|
||||||
|
{{else}}
|
||||||
|
{{#if model.length}}
|
||||||
|
|
||||||
|
<div class='table screened-urls'>
|
||||||
|
<div class="heading-container">
|
||||||
|
<div class="col heading first url">{{i18n admin.logs.screened_urls.url}}</div>
|
||||||
|
<div class="col heading action">{{i18n admin.logs.action}}</div>
|
||||||
|
<div class="col heading match_count">{{i18n admin.logs.match_count}}</div>
|
||||||
|
<div class="col heading last_match_at">{{i18n admin.logs.last_match_at}}</div>
|
||||||
|
<div class="col heading created_at">{{i18n admin.logs.created_at}}</div>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{view Discourse.ScreenedUrlsListView contentBinding="controller"}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{else}}
|
||||||
|
{{i18n search.no_results}}
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
|
@ -0,0 +1,6 @@
|
||||||
|
<div class="col first url">{{url}}</div>
|
||||||
|
<div class="col action">{{actionName}}</div>
|
||||||
|
<div class="col match_count">{{match_count}}</div>
|
||||||
|
<div class="col last_match_at">{{unboundAgeWithTooltip last_match_at}}</div>
|
||||||
|
<div class="col created_at">{{unboundAgeWithTooltip created_at}}</div>
|
||||||
|
<div class="clearfix"></div>
|
|
@ -0,0 +1,5 @@
|
||||||
|
Discourse.ScreenedUrlsListView = Ember.ListView.extend({
|
||||||
|
height: 700,
|
||||||
|
rowHeight: 32,
|
||||||
|
itemViewClass: Ember.ListItemView.extend({templateName: "admin/templates/logs/screened_urls_list_item"})
|
||||||
|
});
|
|
@ -700,9 +700,9 @@ table {
|
||||||
|
|
||||||
// Logs
|
// Logs
|
||||||
|
|
||||||
.blocked-emails {
|
.screened-emails, .screened-urls {
|
||||||
width: 900px;
|
width: 900px;
|
||||||
.email {
|
.email, .url {
|
||||||
width: 400px;
|
width: 400px;
|
||||||
}
|
}
|
||||||
.action, .match_count, .last_match_at, .created_at {
|
.action, .match_count, .last_match_at, .created_at {
|
||||||
|
@ -775,7 +775,7 @@ table {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blocked-emails, .staff-actions {
|
.staff-actions, .screened-emails, .screened-urls {
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
border-bottom: dotted 1px #ddd;
|
border-bottom: dotted 1px #ddd;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
class Admin::ScreenedUrlsController < Admin::AdminController
|
||||||
|
|
||||||
|
def index
|
||||||
|
screened_urls = ScreenedUrl.limit(200).order('last_match_at desc').to_a
|
||||||
|
render_serialized(screened_urls, ScreenedUrlSerializer)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,12 @@
|
||||||
|
class ScreenedUrlSerializer < ApplicationSerializer
|
||||||
|
attributes :url,
|
||||||
|
:domain,
|
||||||
|
:action,
|
||||||
|
:match_count,
|
||||||
|
:last_match_at,
|
||||||
|
:created_at
|
||||||
|
|
||||||
|
def action
|
||||||
|
ScreenedUrl.actions.key(object.action_type).to_s
|
||||||
|
end
|
||||||
|
end
|
|
@ -1181,15 +1181,11 @@ en:
|
||||||
title: "Logs"
|
title: "Logs"
|
||||||
action: "Action"
|
action: "Action"
|
||||||
created_at: "Created"
|
created_at: "Created"
|
||||||
screened_emails:
|
last_match_at: "Last Matched"
|
||||||
title: "Screened Emails"
|
match_count: "Matches"
|
||||||
description: "When someone tries to create a new account, the following email addresses will be checked and the registration will be blocked, or some other action performed."
|
screened_actions:
|
||||||
email: "Email Address"
|
block: "block"
|
||||||
last_match_at: "Last Matched"
|
do_nothing: "do nothing"
|
||||||
match_count: "Matches"
|
|
||||||
actions:
|
|
||||||
block: "block"
|
|
||||||
do_nothing: "do nothing"
|
|
||||||
staff_actions:
|
staff_actions:
|
||||||
title: "Staff Actions"
|
title: "Staff Actions"
|
||||||
instructions: "Click usernames and actions to filter the list. Click avatars to go to user pages."
|
instructions: "Click usernames and actions to filter the list. Click avatars to go to user pages."
|
||||||
|
@ -1202,6 +1198,14 @@ en:
|
||||||
actions:
|
actions:
|
||||||
delete_user: "delete user"
|
delete_user: "delete user"
|
||||||
change_trust_level: "change trust level"
|
change_trust_level: "change trust level"
|
||||||
|
screened_emails:
|
||||||
|
title: "Screened Emails"
|
||||||
|
description: "When someone tries to create a new account, the following email addresses will be checked and the registration will be blocked, or some other action performed."
|
||||||
|
email: "Email Address"
|
||||||
|
screened_urls:
|
||||||
|
title: "Screened URLs"
|
||||||
|
description: "The URLs listed here were used in posts by users who have been identified as spammers."
|
||||||
|
url: "URL"
|
||||||
|
|
||||||
impersonate:
|
impersonate:
|
||||||
title: "Impersonate User"
|
title: "Impersonate User"
|
||||||
|
|
|
@ -64,8 +64,9 @@ Discourse::Application.routes.draw do
|
||||||
end
|
end
|
||||||
|
|
||||||
scope '/logs' do
|
scope '/logs' do
|
||||||
resources :screened_emails, only: [:index, :create, :update, :destroy]
|
resources :staff_action_logs, only: [:index]
|
||||||
resources :staff_action_logs, only: [:index, :create, :update, :destroy]
|
resources :screened_emails, only: [:index]
|
||||||
|
resources :screened_urls, only: [:index]
|
||||||
end
|
end
|
||||||
|
|
||||||
get 'customize' => 'site_customizations#index', constraints: AdminConstraint.new
|
get 'customize' => 'site_customizations#index', constraints: AdminConstraint.new
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Admin::ScreenedUrlsController do
|
||||||
|
it "is a subclass of AdminController" do
|
||||||
|
(Admin::ScreenedUrlsController < Admin::AdminController).should be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
let!(:user) { log_in(:admin) }
|
||||||
|
|
||||||
|
context '.index' do
|
||||||
|
before do
|
||||||
|
xhr :get, :index
|
||||||
|
end
|
||||||
|
|
||||||
|
subject { response }
|
||||||
|
it { should be_success }
|
||||||
|
|
||||||
|
it 'returns JSON' do
|
||||||
|
::JSON.parse(subject.body).should be_a(Array)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue