Skip to content

Commit 0639a6a

Browse files
committed
working version
1 parent 3fca8a8 commit 0639a6a

File tree

4 files changed

+70
-51
lines changed

4 files changed

+70
-51
lines changed

README.md

+14-39
Original file line numberDiff line numberDiff line change
@@ -14,50 +14,31 @@ Create a rule to forward email to this plugin
1414

1515
```
1616
match_recipient(“reply-.*@mydiscourse.domain”)
17-
forward(“https://mydiscourse.domain/admin/plugin/mailgun”)
17+
forward(“https://mydiscourse.domain/mailgun/incoming”)
1818
```
1919

2020
### Installing
2121

22-
A step by step series of examples that tell you have to get a development env running
23-
24-
Say what the step will be
25-
26-
```
27-
Give the example
28-
```
29-
30-
And repeat
31-
32-
```
33-
until finished
34-
```
35-
36-
End with an example of getting some data out of the system or using it for a little demo
22+
Installing this plugin should be as simple as following the [Discourse Plugin installation tutorial](https://meta.discourse.org/t/install-a-plugin/19157)
3723

3824
## Running the tests
3925

40-
Explain how to run the automated tests for this system
41-
42-
### Break down into end to end tests
26+
In order to run tests you'll need a Discourse development environment such as the [vagrant](https://github.com/discourse/discourse/blob/master/docs/VAGRANT.md) one.
4327

44-
Explain what these tests test and why
28+
You can then run the tests with `rake plugin:spec[discourse-mailgun]`
4529

46-
```
47-
Give an example
48-
```
30+
## Deployment
4931

50-
### And coding style tests
32+
Once the plugin is installed, you'll need to configure a few things:
5133

52-
Explain what these tests test and why
34+
* Mailgun API key - which you can retrieve in your mailgun settings
35+
* Discourse Base URL - the URL where your discourse is available
36+
* Discourse API key - you can create one in the discourse admin panel
37+
* Discourse API username
5338

54-
```
55-
Give an example
56-
```
39+
You can do this in the plugin settings page.
5740

58-
## Deployment
59-
60-
Once the plugin is installed, you'll need to configure your Mailgun API key. You can do this in the plugin settings page.
41+
You'll also need to enable "manual polling enabled" in your discourse email settings admin panel.
6142

6243
## Built With
6344

@@ -71,20 +52,14 @@ Please read [CONTRIBUTING.md](https://gist.github.com/PurpleBooth/b24679402957c6
7152

7253
## Versioning
7354

74-
We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/your/project/tags).
55+
We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/reallyreally/discourse-mailgun/tags).
7556

7657
## Authors
7758

78-
* **Author Name** - *Initial work* - [Company](https://really.ai/)
59+
* **Tiago Macedo** - *Initial work* - [Really Really Inc](https://really.ai/)
7960

8061
See also the list of [contributors](https://github.com/reallyreally/discourse-mailgun/contributors) who participated in this project.
8162

8263
## License
8364

8465
This project is licensed under the Apache 2.0 - see the [LICENSE.md](LICENSE.md) file for details
85-
86-
## Acknowledgments
87-
88-
* Hat tip to anyone who's code was used
89-
* Inspiration
90-
* etc

config/settings.yml

+9
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,12 @@ plugins:
22
mailgun_api_key:
33
default: your_mailgun_api_key
44
client: false
5+
discourse_base_url:
6+
default: https://some-url.com
7+
client: false
8+
discourse_api_key:
9+
default: some-api-key
10+
client: false
11+
discourse_api_username:
12+
default: api_username
13+
client: false

plugin.rb

+31-12
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,28 @@
77
require 'openssl'
88

99
after_initialize do
10-
1110
module ::DiscourseMailgun
1211
class Engine < ::Rails::Engine
1312
engine_name "discourse-mailgun"
1413
isolate_namespace DiscourseMailgun
14+
15+
class << self
16+
# signature verification filter
17+
def verify_signature(timestamp, token, signature, api_key)
18+
digest = OpenSSL::Digest::SHA256.new
19+
data = [timestamp, token].join
20+
hex = OpenSSL::HMAC.hexdigest(digest, api_key, data)
21+
22+
signature == hex
23+
end
24+
25+
# posting the email through the discourse api
26+
def post(url, params)
27+
Excon.post(url,
28+
:body => URI.encode_www_form(params),
29+
:headers => { "Content-Type" => "application/x-www-form-urlencoded" })
30+
end
31+
end
1532
end
1633
end
1734

@@ -20,7 +37,7 @@ class Engine < ::Rails::Engine
2037
class DiscourseMailgun::MailgunController < ::ApplicationController
2138
before_filter :verify_signature
2239

23-
def webhook
40+
def incoming
2441
mg_body = params['body-plain']
2542
mg_subj = params['subject']
2643
mg_to = params['To']
@@ -35,9 +52,14 @@ def webhook
3552
body mg_body
3653
end
3754

38-
raw_email = m.to_s
55+
handler_url = SiteSetting.discourse_base_url + "/admin/email/handle_mail"
3956

40-
render json: "done"
57+
params = {'email' => m.to_s,
58+
'api_key' => SiteSetting.discourse_api_key,
59+
'api_username' => SiteSetting.discourse_api_username}
60+
::DiscourseMailgun::Engine.post(handler_url, params)
61+
62+
render plain: "done"
4163
end
4264

4365
# we mark this controller as an API
@@ -46,21 +68,18 @@ def is_api?
4668
true
4769
end
4870

49-
private
71+
private
5072

51-
# signature verification filter
5273
def verify_signature
53-
digest = OpenSSL::Digest::SHA256.new
54-
data = [params['timestamp'], params['token']].join
55-
hex = OpenSSL::HMAC.hexdigest(digest, SiteSetting.mailgun_api_key, data)
56-
57-
render json: {}, :status => :unauthorized unless params['signature'] == hex
74+
unless ::DiscourseMailgun::Engine.verify_signature(params['timestamp'], params['token'], params['signature'], SiteSetting.mailgun_api_key)
75+
render json: {}, :status => :unauthorized
76+
end
5877
end
5978
end
6079

6180

6281
DiscourseMailgun::Engine.routes.draw do
63-
post "/webhook" => "mailgun#webhook"
82+
post "/incoming" => "mailgun#incoming"
6483
end
6584

6685
Discourse::Application.routes.append do

spec/engine_spec.rb

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
require 'rails_helper'
2+
3+
describe DiscourseMailgun do
4+
it "fails signature verification on an invalid input" do
5+
expect(DiscourseMailgun::Engine.verify_signature('timestamp', 'token', 'sig', 'key')).to eq(false)
6+
end
7+
8+
it "succeeds with correct input" do
9+
token = "d36d8af15b9694f9077abc4bb1be5475d4e9953329c9c0085e"
10+
sig = "925a06d45995704642609e93ae5e526ded7a0e2413f4094e794851c06b2561d6"
11+
ts = "1500815643"
12+
key = "key-ba22e794c07d6aacc4b0c51a2a7f615d"
13+
14+
expect(DiscourseMailgun::Engine.verify_signature(ts, token, sig, key)).to eq(true)
15+
end
16+
end

0 commit comments

Comments
 (0)