Commit e4e973102763e3b34410c25b46c6246bb3a65320

Authored by Marcin Ciunelis
2 parents ef8950e5 37355272
Exists in master and in 1 other branch production

Merge branch 'master' into head-and-tail

@@ -144,10 +144,10 @@ git clone http://github.com/errbit/errbit.git @@ -144,10 +144,10 @@ git clone http://github.com/errbit/errbit.git
144 ```bash 144 ```bash
145 gem install heroku 145 gem install heroku
146 heroku create example-errbit --stack cedar 146 heroku create example-errbit --stack cedar
147 -heroku addons:add mongohq:free  
148 -cp -f config/mongoid.mongohq.yml config/mongoid.yml 147 +heroku addons:add mongolab:starter
  148 +cp -f config/mongoid.mongolab.yml config/mongoid.yml
149 git add -f config/mongoid.yml 149 git add -f config/mongoid.yml
150 -git commit -m "Added mongoid config for MongoHQ" 150 +git commit -m "Added mongoid config for Mongolab"
151 heroku addons:add sendgrid:starter 151 heroku addons:add sendgrid:starter
152 heroku config:add HEROKU=true 152 heroku config:add HEROKU=true
153 heroku config:add ERRBIT_HOST=some-hostname.example.com 153 heroku config:add ERRBIT_HOST=some-hostname.example.com
@@ -191,7 +191,7 @@ heroku run rake db:seed @@ -191,7 +191,7 @@ heroku run rake db:seed
191 * You may want to enable the deployment hook for heroku : 191 * You may want to enable the deployment hook for heroku :
192 192
193 ```bash 193 ```bash
194 -heroku addons:add deployhooks:http url="http://YOUR_ERRBIT_HOST/deploys.txt?api_key=YOUR_API_KEY" 194 +heroku addons:add deployhooks:http --url="http://YOUR_ERRBIT_HOST/deploys.txt?api_key=YOUR_API_KEY"
195 ``` 195 ```
196 196
197 * Enjoy! 197 * Enjoy!
@@ -233,6 +233,43 @@ You can change the requested account permissions by setting `github_access_scope @@ -233,6 +233,43 @@ You can change the requested account permissions by setting `github_access_scope
233 </table> 233 </table>
234 234
235 235
  236 +### GitHub authentication when served on Heroku
  237 +
  238 +You will need to set up Heroku variables accordingly as described in [Configuring GitHub authentication](#configuring-github-authentication):
  239 +
  240 +* GITHUB_AUTHENTICATION
  241 +
  242 +```bash
  243 +heroku config:add GITHUB_AUTHENTICATION=true
  244 +```
  245 +
  246 +* GITHUB_CLIENT_ID
  247 +
  248 +```bash
  249 +heroku config:add GITHUB_CLIENT_ID=the_client_id_provided_by_GitHub
  250 +```
  251 +
  252 +* GITHUB_SECRET
  253 +
  254 +```bash
  255 +heroku config:add GITHUB_SECRET=the_secret_provided_by_GitHub
  256 +```
  257 +
  258 +* GITHUB_ACCESS_SCOPE - set only one scope `repo` or `public_repo`. If you really need to put more than one, separate them with comma.
  259 +
  260 +```bash
  261 +heroku config:add GITHUB_ACCESS_SCOPE=repo,public_repo
  262 +```
  263 +
  264 +__Note__: To avoid restarting your Heroku app 4 times you can set Heroku variables in a single command, i.e:
  265 +
  266 +```bash
  267 +heroku config:add GITHUB_AUTHENTICATION=true \
  268 +GITHUB_CLIENT_ID=the_client_id_provided_by_GitHub \
  269 +GITHUB_SECRET=the_secret_provided_by_GitHub \
  270 +GITHUB_ACCESS_SCOPE=repo,public_repo
  271 +```
  272 +
236 ### Configuring LDAP authentication: 273 ### Configuring LDAP authentication:
237 274
238 * In `config/config.yml`, set `user_has_username` to `true` 275 * In `config/config.yml`, set `user_has_username` to `true`
app/assets/stylesheets/errbit.css
@@ -648,6 +648,13 @@ table.errs td.app .environment { @@ -648,6 +648,13 @@ table.errs td.app .environment {
648 table.errs td.message a { 648 table.errs td.message a {
649 display: block; 649 display: block;
650 word-wrap: break-word; 650 word-wrap: break-word;
  651 + /* PjpG - configuration in WHAT & WHERE table's columns using ellipsis to avoid oversizing table's width */
  652 + width: 300px;
  653 + overflow: hidden;
  654 + text-overflow: ellipsis;
  655 + -o-text-overflow: ellipsis;
  656 + white-space: nowrap;
  657 + /* ------ */
651 } 658 }
652 table.errs td.message em { 659 table.errs td.message em {
653 color: #727272; 660 color: #727272;
app/controllers/notices_controller.rb
@@ -5,9 +5,17 @@ class NoticesController &lt; ApplicationController @@ -5,9 +5,17 @@ class NoticesController &lt; ApplicationController
5 5
6 def create 6 def create
7 # params[:data] if the notice came from a GET request, raw_post if it came via POST 7 # params[:data] if the notice came from a GET request, raw_post if it came via POST
8 - @notice = App.report_error!(params[:data] || request.raw_post)  
9 - respond_with @notice 8 + notice = App.report_error!(params[:data] || request.raw_post)
  9 + api_xml = notice.to_xml(:only => false, :methods => [:id]) do |xml|
  10 + xml.url locate_url(notice.id, :host => Errbit::Config.host)
  11 + end
  12 + render :xml => api_xml
10 end 13 end
11 14
  15 + # Redirects a notice to the problem page. Useful when using User Information at Airbrake gem.
  16 + def locate
  17 + problem = Notice.find(params[:id]).problem
  18 + redirect_to app_err_path(problem.app, problem)
  19 + end
12 end 20 end
13 21
config/initializers/_load_config.rb
@@ -9,7 +9,7 @@ unless defined?(Errbit::Config) @@ -9,7 +9,7 @@ unless defined?(Errbit::Config)
9 if ENV['HEROKU'] 9 if ENV['HEROKU']
10 Errbit::Config.host = ENV['ERRBIT_HOST'] 10 Errbit::Config.host = ENV['ERRBIT_HOST']
11 Errbit::Config.email_from = ENV['ERRBIT_EMAIL_FROM'] 11 Errbit::Config.email_from = ENV['ERRBIT_EMAIL_FROM']
12 - Errbit::Config.email_at_notices = [1,3,10] #ENV['ERRBIT_EMAIL_AT_NOTICES'] 12 + Errbit::Config.email_at_notices = ENV['ERRBIT_EMAIL_AT_NOTICES']
13 Errbit::Config.confirm_resolve_err = ENV['ERRBIT_CONFIRM_RESOLVE_ERR'] 13 Errbit::Config.confirm_resolve_err = ENV['ERRBIT_CONFIRM_RESOLVE_ERR']
14 Errbit::Config.user_has_username = ENV['ERRBIT_USER_HAS_USERNAME'] 14 Errbit::Config.user_has_username = ENV['ERRBIT_USER_HAS_USERNAME']
15 Errbit::Config.allow_comments_with_issue_tracker = ENV['ERRBIT_ALLOW_COMMENTS_WITH_ISSUE_TRACKER'] 15 Errbit::Config.allow_comments_with_issue_tracker = ENV['ERRBIT_ALLOW_COMMENTS_WITH_ISSUE_TRACKER']
config/initializers/mongo.rb
1 -if mongo = ENV['MONGOHQ_URL'] || ENV['MONGOLAB_URI'] 1 +if mongo = ENV['MONGOLAB_URI'] || ENV['MONGOHQ_URL']
2 settings = URI.parse(mongo) 2 settings = URI.parse(mongo)
3 database_name = settings.path.gsub(/^\//, '') 3 database_name = settings.path.gsub(/^\//, '')
4 4
config/mongoid.mongolab.yml 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +# Mongoid Configuration for MongoLab on Heroku
  2 +# ===========================================
  3 +#
  4 +# Copy this file to config/mongoid.yml,
  5 +# commit it to your repo, then push to heroku.
  6 +
  7 +production:
  8 + uri: <%= ENV['MONGOLAB_URI'] %>
config/routes.rb
@@ -4,6 +4,7 @@ Errbit::Application.routes.draw do @@ -4,6 +4,7 @@ Errbit::Application.routes.draw do
4 4
5 # Hoptoad Notifier Routes 5 # Hoptoad Notifier Routes
6 match '/notifier_api/v2/notices' => 'notices#create' 6 match '/notifier_api/v2/notices' => 'notices#create'
  7 + match '/locate/:id' => 'notices#locate', :as => :locate
7 match '/deploys.txt' => 'deploys#create' 8 match '/deploys.txt' => 'deploys#create'
8 9
9 resources :notices, :only => [:show] 10 resources :notices, :only => [:show]
spec/controllers/notices_controller_spec.rb
1 require 'spec_helper' 1 require 'spec_helper'
2 2
3 describe NoticesController do 3 describe NoticesController do
  4 + it_requires_authentication :for => { :locate => :get }
  5 +
  6 + let(:app) { Fabricate(:app) }
4 7
5 context 'notices API' do 8 context 'notices API' do
6 before do 9 before do
@@ -8,25 +11,34 @@ describe NoticesController do @@ -8,25 +11,34 @@ describe NoticesController do
8 @app = Fabricate(:app_with_watcher) 11 @app = Fabricate(:app_with_watcher)
9 App.stub(:find_by_api_key!).and_return(@app) 12 App.stub(:find_by_api_key!).and_return(@app)
10 @notice = App.report_error!(@xml) 13 @notice = App.report_error!(@xml)
11 -  
12 - request.env['Content-type'] = 'text/xml'  
13 - request.env['Accept'] = 'text/xml, application/xml'  
14 end 14 end
15 15
16 it "generates a notice from xml [POST]" do 16 it "generates a notice from xml [POST]" do
17 App.should_receive(:report_error!).with(@xml).and_return(@notice) 17 App.should_receive(:report_error!).with(@xml).and_return(@notice)
18 request.should_receive(:raw_post).and_return(@xml) 18 request.should_receive(:raw_post).and_return(@xml)
19 - post :create 19 + post :create, :format => :xml
  20 + response.should be_success
  21 + # Same RegExp from Airbrake::Sender#send_to_airbrake (https://github.com/airbrake/airbrake/blob/master/lib/airbrake/sender.rb#L53)
  22 + # Inspired by https://github.com/airbrake/airbrake/blob/master/test/sender_test.rb
  23 + response.body.should match(%r{<id[^>]*>#{@notice.id}</id>})
  24 + response.body.should match(%r{<url[^>]*>(.+)#{locate_path(@notice.id)}</url>})
20 end 25 end
21 26
22 it "generates a notice from xml [GET]" do 27 it "generates a notice from xml [GET]" do
23 App.should_receive(:report_error!).with(@xml).and_return(@notice) 28 App.should_receive(:report_error!).with(@xml).and_return(@notice)
24 - get :create, {:data => @xml} 29 + get :create, :data => @xml, :format => :xml
  30 + response.should be_success
  31 + response.body.should match(%r{<id[^>]*>#{@notice.id}</id>})
  32 + response.body.should match(%r{<url[^>]*>(.+)#{locate_path(@notice.id)}</url>})
25 end 33 end
26 34
27 it "sends a notification email" do 35 it "sends a notification email" do
  36 + App.should_receive(:report_error!).with(@xml).and_return(@notice)
28 request.should_receive(:raw_post).and_return(@xml) 37 request.should_receive(:raw_post).and_return(@xml)
29 - post :create 38 + post :create, :format => :xml
  39 + response.should be_success
  40 + response.body.should match(%r{<id[^>]*>#{@notice.id}</id>})
  41 + response.body.should match(%r{<url[^>]*>(.+)#{locate_path(@notice.id)}</url>})
30 email = ActionMailer::Base.deliveries.last 42 email = ActionMailer::Base.deliveries.last
31 email.to.should include(@app.watchers.first.email) 43 email.to.should include(@app.watchers.first.email)
32 email.subject.should include(@notice.message) 44 email.subject.should include(@notice.message)
@@ -35,5 +47,21 @@ describe NoticesController do @@ -35,5 +47,21 @@ describe NoticesController do
35 end 47 end
36 end 48 end
37 49
  50 + describe "GET /locate/:id" do
  51 + context 'when logged in as an admin' do
  52 + before(:each) do
  53 + @user = Fabricate(:admin)
  54 + sign_in @user
  55 + end
  56 +
  57 + it "should locate notice and redirect to problem" do
  58 + problem = Fabricate(:problem, :app => app, :environment => "production")
  59 + notice = Fabricate(:notice, :err => Fabricate(:err, :problem => problem))
  60 + get :locate, :id => notice.id
  61 + response.should redirect_to(app_err_path(problem.app, problem))
  62 + end
  63 + end
  64 + end
  65 +
38 end 66 end
39 67