Commit e4e973102763e3b34410c25b46c6246bb3a65320
Exists in
master
and in
1 other branch
Merge branch 'master' into head-and-tail
Showing
8 changed files
with
103 additions
and
14 deletions
Show diff stats
README.md
| @@ -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 < ApplicationController | @@ -5,9 +5,17 @@ class NoticesController < 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
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 |