diff --git a/app/assets/javascripts/discourse/controllers/raw-email.js.es6 b/app/assets/javascripts/discourse/controllers/raw-email.js.es6
new file mode 100644
index 00000000000..01f637a7bec
--- /dev/null
+++ b/app/assets/javascripts/discourse/controllers/raw-email.js.es6
@@ -0,0 +1,24 @@
+import ModalFunctionality from 'discourse/mixins/modal-functionality';
+
+import ObjectController from 'discourse/controllers/object';
+
+/**
+ This controller handles displaying of raw email
+
+ @class RawEmailController
+ @extends ObjectController
+ @namespace Discourse
+ @uses ModalFunctionality
+ @module Discourse
+**/
+export default ObjectController.extend(ModalFunctionality, {
+ raw_email: "",
+
+ loadRawEmail: function(postId) {
+ var self = this;
+ Discourse.Post.loadRawEmail(postId).then(function (raw_email) {
+ self.set("raw_email", raw_email);
+ });
+ }
+
+});
diff --git a/app/assets/javascripts/discourse/models/_post.js b/app/assets/javascripts/discourse/models/_post.js
index 620baf40138..118afce2997 100644
--- a/app/assets/javascripts/discourse/models/_post.js
+++ b/app/assets/javascripts/discourse/models/_post.js
@@ -64,6 +64,10 @@ Discourse.Post = Discourse.Model.extend({
hasHistory: Em.computed.gt('version', 1),
postElementId: Discourse.computed.fmt('post_number', 'post_%@'),
+ canViewRawEmail: function() {
+ return Discourse.User.currentProp('staff');
+ }.property(),
+
bookmarkedChanged: function() {
Discourse.Post.bookmark(this.get('id'), this.get('bookmarked'))
.then(null, function (error) {
@@ -486,6 +490,12 @@ Discourse.Post.reopenClass({
});
},
+ loadRawEmail: function(postId) {
+ return Discourse.ajax("/posts/" + postId + "/raw-email").then(function (result) {
+ return result.raw_email;
+ });
+ },
+
load: function(postId) {
return Discourse.ajax("/posts/" + postId + ".json").then(function (result) {
return Discourse.Post.create(result);
diff --git a/app/assets/javascripts/discourse/routes/topic_route.js b/app/assets/javascripts/discourse/routes/topic_route.js
index a02a635bc67..462845ef71f 100644
--- a/app/assets/javascripts/discourse/routes/topic_route.js
+++ b/app/assets/javascripts/discourse/routes/topic_route.js
@@ -73,6 +73,11 @@ Discourse.TopicRoute = Discourse.Route.extend({
this.controllerFor('modal').set('modalClass', 'history-modal');
},
+ showRawEmail: function(post) {
+ Discourse.Route.showModal(this, 'raw-email', post);
+ this.controllerFor('raw_email').loadRawEmail(post.get("id"));
+ },
+
mergeTopic: function() {
Discourse.Route.showModal(this, 'mergeTopic', this.modelFor('topic'));
},
diff --git a/app/assets/javascripts/discourse/templates/modal/raw_email.hbs b/app/assets/javascripts/discourse/templates/modal/raw_email.hbs
new file mode 100644
index 00000000000..63e9256d942
--- /dev/null
+++ b/app/assets/javascripts/discourse/templates/modal/raw_email.hbs
@@ -0,0 +1,7 @@
+
+ {{#if raw_email}}
+
{{raw_email}}
+ {{else}}
+ {{i18n raw_email.not_available}}
+ {{/if}}
+
diff --git a/app/assets/javascripts/discourse/templates/post.hbs b/app/assets/javascripts/discourse/templates/post.hbs
index f9bf8059de4..90f06f2917c 100644
--- a/app/assets/javascripts/discourse/templates/post.hbs
+++ b/app/assets/javascripts/discourse/templates/post.hbs
@@ -53,7 +53,11 @@
{{/if}}
{{#if via_email}}
-
+ {{#if canViewRawEmail}}
+
+ {{else}}
+
+ {{/if}}
{{/if}}
diff --git a/app/assets/javascripts/discourse/views/raw-email.es6 b/app/assets/javascripts/discourse/views/raw-email.es6
new file mode 100644
index 00000000000..d529b1063b7
--- /dev/null
+++ b/app/assets/javascripts/discourse/views/raw-email.es6
@@ -0,0 +1,9 @@
+export default Discourse.ModalBodyView.extend({
+ templateName: 'modal/raw_email',
+ title: I18n.t('raw_email.title'),
+
+ resizeModal: function(){
+ var viewPortHeight = $(window).height();
+ this.$(".modal-body").css("max-height", Math.floor(0.8 * viewPortHeight) + "px");
+ }.on("didInsertElement")
+});
diff --git a/app/assets/stylesheets/common/base/topic-post.scss b/app/assets/stylesheets/common/base/topic-post.scss
index 926264e0952..0626826bf3a 100644
--- a/app/assets/stylesheets/common/base/topic-post.scss
+++ b/app/assets/stylesheets/common/base/topic-post.scss
@@ -135,6 +135,9 @@ aside.quote {
&.via-email {
color: scale-color($primary, $lightness: 70%);
}
+ &.raw-email {
+ cursor: pointer;
+ }
}
diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb
index e52b5f0fd5b..14fbc4acbf6 100644
--- a/app/controllers/posts_controller.rb
+++ b/app/controllers/posts_controller.rb
@@ -30,6 +30,12 @@ class PostsController < ApplicationController
render json: {cooked: post.cooked}
end
+ def raw_email
+ guardian.ensure_can_view_raw_email!
+ post = Post.find(params[:id].to_i)
+ render json: {raw_email: post.raw_email}
+ end
+
def short_link
post = Post.find(params[:post_id].to_i)
# Stuff the user in the request object, because that's what IncomingLink wants
diff --git a/app/models/post.rb b/app/models/post.rb
index 0d311af67d9..91c0de77ac2 100644
--- a/app/models/post.rb
+++ b/app/models/post.rb
@@ -606,6 +606,8 @@ end
# version :integer default(1), not null
# cook_method :integer default(1), not null
# wiki :boolean default(FALSE), not null
+# via_email :boolean default(FALSE), not null
+# raw_email :text
# baked_at :datetime
# baked_version :integer
# hidden_at :datetime
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 7fb27b02a38..87fb3c8713d 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -1384,6 +1384,10 @@ en:
history: "History"
changed_by: "by {{author}}"
+ raw_email:
+ title: "Raw Email"
+ not_available: "Not available!"
+
categories_list: "Categories List"
filters:
diff --git a/config/routes.rb b/config/routes.rb
index 1bac1c7d187..9650af142b6 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -416,6 +416,7 @@ Discourse::Application.routes.draw do
get "/posts/:id/cooked" => "posts#cooked"
get "/posts/:id/expand-embed" => "posts#expand_embed"
get "/posts/:id/raw" => "posts#markdown_id"
+ get "/posts/:id/raw-email" => "posts#raw_email"
get "raw/:topic_id(/:post_number)" => "posts#markdown_num"
resources :invites do
diff --git a/db/migrate/20141015060145_add_raw_email_to_posts.rb b/db/migrate/20141015060145_add_raw_email_to_posts.rb
new file mode 100644
index 00000000000..2c3b89b6d64
--- /dev/null
+++ b/db/migrate/20141015060145_add_raw_email_to_posts.rb
@@ -0,0 +1,5 @@
+class AddRawEmailToPosts < ActiveRecord::Migration
+ def change
+ add_column :posts, :raw_email, :text
+ end
+end
diff --git a/lib/email/receiver.rb b/lib/email/receiver.rb
index a007965130a..4ca8032cf21 100644
--- a/lib/email/receiver.rb
+++ b/lib/email/receiver.rb
@@ -245,6 +245,7 @@ module Email
def create_post(user, options)
# Mark the reply as incoming via email
options[:via_email] = true
+ options[:raw_email] = @raw
creator = PostCreator.new(user, options)
post = creator.create
diff --git a/lib/guardian/post_guardian.rb b/lib/guardian/post_guardian.rb
index 4da4acf03d8..7eae1a89f3b 100644
--- a/lib/guardian/post_guardian.rb
+++ b/lib/guardian/post_guardian.rb
@@ -193,6 +193,10 @@ module PostGuardian
is_staff?
end
+ def can_view_raw_email?
+ is_staff?
+ end
+
def can_unhide?(post)
post.try(:hidden) && is_staff?
end
diff --git a/lib/post_creator.rb b/lib/post_creator.rb
index 2eb4d6c1b5a..ae1c6fc178f 100644
--- a/lib/post_creator.rb
+++ b/lib/post_creator.rb
@@ -223,7 +223,7 @@ class PostCreator
reply_to_post_number: @opts[:reply_to_post_number])
# Attributes we pass through to the post instance if present
- [:post_type, :no_bump, :cooking_options, :image_sizes, :acting_user, :invalidate_oneboxes, :cook_method, :via_email].each do |a|
+ [:post_type, :no_bump, :cooking_options, :image_sizes, :acting_user, :invalidate_oneboxes, :cook_method, :via_email, :raw_email].each do |a|
post.send("#{a}=", @opts[a]) if @opts[a].present?
end
diff --git a/spec/components/email/receiver_spec.rb b/spec/components/email/receiver_spec.rb
index c5e7c9c4fa3..f5484fa0bb5 100644
--- a/spec/components/email/receiver_spec.rb
+++ b/spec/components/email/receiver_spec.rb
@@ -146,6 +146,7 @@ Pleasure to have you here!
topic.posts.count.should == (start_count + 1)
created_post = topic.posts.last
created_post.via_email.should == true
+ created_post.raw_email.should == fixture_file("emails/valid_reply.eml")
created_post.cooked.strip.should == fixture_file("emails/valid_reply.cooked").strip
end
end
diff --git a/spec/controllers/posts_controller_spec.rb b/spec/controllers/posts_controller_spec.rb
index 04690e02390..dd28e3af048 100644
--- a/spec/controllers/posts_controller_spec.rb
+++ b/spec/controllers/posts_controller_spec.rb
@@ -68,6 +68,36 @@ describe PostsController do
end
end
+ describe 'raw_email' do
+ include_examples "action requires login", :get, :raw_email, id: 2
+
+ describe "when logged in" do
+ let(:user) {log_in}
+ let(:post) {Fabricate(:post, user: user, raw_email: 'email_content')}
+
+ it "raises an error if the user doesn't have permission to view raw email" do
+ Guardian.any_instance.expects(:can_view_raw_email?).returns(false)
+
+ xhr :get, :raw_email, id: post.id
+
+ response.should be_forbidden
+ end
+
+ it "can view raw email" do
+ Guardian.any_instance.expects(:can_view_raw_email?).returns(true)
+
+ xhr :get, :raw_email, id: post.id
+
+ response.should be_success
+ json = ::JSON.parse(response.body)
+ json.should be_present
+ json['raw_email'].should == 'email_content'
+ end
+
+ end
+
+ end
+
describe 'show' do
include_examples 'finding and showing post' do
let(:action) { :show }