Commit 8f13caf0bffe3dfd579dc52b76f54fe84c943154

Authored by Cyril Mougel
1 parent b4fc56cc
Exists in master and in 1 other branch production

Add capabilities to addmin to regenerate the API key of his app

Now the api_key of app can be regenerate. In previous this api-key can't
be regenerate by the web front. To regenerate this api_key you need go
to the edit app page.

See #547
app/controllers/apps_controller.rb
@@ -80,6 +80,11 @@ class AppsController < ApplicationController @@ -80,6 +80,11 @@ class AppsController < ApplicationController
80 end 80 end
81 end 81 end
82 82
  83 + def regenerate_api_key
  84 + app.regenerate_api_key!
  85 + redirect_to edit_app_path(app)
  86 + end
  87 +
83 protected 88 protected
84 89
85 def initialize_subclassed_issue_tracker 90 def initialize_subclassed_issue_tracker
app/models/app.rb
@@ -170,6 +170,10 @@ class App @@ -170,6 +170,10 @@ class App
170 Errbit::Config.per_app_email_at_notices ? super : Errbit::Config.email_at_notices 170 Errbit::Config.per_app_email_at_notices ? super : Errbit::Config.email_at_notices
171 end 171 end
172 172
  173 + def regenerate_api_key!
  174 + set(:api_key, SecureRandom.hex)
  175 + end
  176 +
173 protected 177 protected
174 178
175 def store_cached_attributes_on_problems 179 def store_cached_attributes_on_problems
app/views/apps/_fields.html.haml
@@ -5,6 +5,10 @@ @@ -5,6 +5,10 @@
5 = f.text_field :name 5 = f.text_field :name
6 6
7 %div 7 %div
  8 + %label Api Key
  9 + %span= app.api_key
  10 + = link_to t('.regenerate_api_key'), regenerate_api_key_app_path(app), :class => 'button', :method => 'post'
  11 +%div
8 = f.label :repository_branch 12 = f.label :repository_branch
9 = f.text_field :repository_branch, :placeholder => "master" 13 = f.text_field :repository_branch, :placeholder => "master"
10 %div 14 %div
config/locales/en.yml
@@ -81,6 +81,8 @@ en: @@ -81,6 +81,8 @@ en:
81 new_app: Add a New App 81 new_app: Add a New App
82 no_apps: 'No apps here.' 82 no_apps: 'No apps here.'
83 click_to_create: 'Click here to create your first one' 83 click_to_create: 'Click here to create your first one'
  84 + fields:
  85 + regenerate_api_key: "Regenerate API key"
84 show: 86 show:
85 all_deploys: "All Deploys (%{count})" 87 all_deploys: "All Deploys (%{count})"
86 all_errs: all errs 88 all_errs: all errs
@@ -100,7 +102,6 @@ en: @@ -100,7 +102,6 @@ en:
100 no_error_yet: "No errs have been caught yet, make sure you setup your app" 102 no_error_yet: "No errs have been caught yet, make sure you setup your app"
101 no_watcher: "Sadly, no one is watching this app" 103 no_watcher: "Sadly, no one is watching this app"
102 repository: Repository 104 repository: Repository
103 - repository: Repository  
104 revision: Revision 105 revision: Revision
105 search_placeholder: 'Search for issues' 106 search_placeholder: 'Search for issues'
106 show_hide: "(show/hide)" 107 show_hide: "(show/hide)"
@@ -110,3 +111,4 @@ en: @@ -110,3 +111,4 @@ en:
110 watchers: Watchers 111 watchers: Watchers
111 when: When 112 when: When
112 who: Who 113 who: Who
  114 +
config/routes.rb
@@ -39,6 +39,9 @@ Errbit::Application.routes.draw do @@ -39,6 +39,9 @@ Errbit::Application.routes.draw do
39 end 39 end
40 resources :deploys, :only => [:index] 40 resources :deploys, :only => [:index]
41 resources :watchers, :only => [:destroy] 41 resources :watchers, :only => [:destroy]
  42 + member do
  43 + post :regenerate_api_key
  44 + end
42 end 45 end
43 46
44 namespace :api do 47 namespace :api do
spec/acceptance/acceptance_helper.rb
@@ -17,3 +17,10 @@ def mock_auth(user = "test_user", token = "abcdef") @@ -17,3 +17,10 @@ def mock_auth(user = "test_user", token = "abcdef")
17 } 17 }
18 ) 18 )
19 end 19 end
  20 +
  21 +def log_in(user)
  22 + visit '/'
  23 + fill_in :user_email, :with => user.email
  24 + fill_in :user_password, :with => 'password'
  25 + click_on I18n.t('devise.sessions.new.sign_in')
  26 +end
spec/acceptance/app_regenerate_api_key_spec.rb 0 → 100644
@@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
  1 +require 'acceptance/acceptance_helper'
  2 +
  3 +feature "Regeneration api_Key" do
  4 + let!(:app) { Fabricate(:app) }
  5 + let!(:admin) { Fabricate(:admin) }
  6 + let(:user) {
  7 + Fabricate(:user_watcher, :app => app).user
  8 + }
  9 +
  10 + scenario "an admin change api_key" do
  11 + visit '/'
  12 + log_in admin
  13 + click_link app.name
  14 + click_link I18n.t('apps.show.edit')
  15 + expect {
  16 + click_link I18n.t('apps.fields.regenerate_api_key')
  17 + }.to change {
  18 + app.reload.api_key
  19 + }
  20 + end
  21 +
  22 + scenario "a user cannot access to edit page" do
  23 + visit '/'
  24 + log_in user
  25 + click_link app.name if page.current_url != app_url(app)
  26 + expect(page).to_not have_button I18n.t('apps.show.edit')
  27 + end
  28 +
  29 +end
spec/acceptance/watch_unwatch_app.rb
@@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
1 -require 'acceptance/acceptance_helper'  
2 -  
3 -feature 'A user can watch and unwatch an application' do  
4 -  
5 - let!(:app) { Fabricate(:app) }  
6 - let!(:user) do  
7 - user = Fabricate(:user)  
8 - app.watchers.create!(  
9 - :user_id => user.id  
10 - )  
11 - user.reload  
12 - end  
13 -  
14 - scenario 'log in watch a project and unwatch it' do  
15 - visit '/'  
16 - fill_in :user_email, :with => user.email  
17 - fill_in :user_password, :with => 'password'  
18 - click_on I18n.t('devise.sessions.new.sign_in')  
19 - click_on I18n.t('apps.show.unwatch')  
20 - expect(page).to have_content(I18n.t('apps.index.no_apps')  
21 - end  
22 -  
23 -end  
spec/acceptance/watch_unwatch_app_spec.rb 0 → 100644
@@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
  1 +require 'acceptance/acceptance_helper'
  2 +
  3 +feature 'A user can watch and unwatch an application' do
  4 +
  5 + let!(:app) { Fabricate(:app) }
  6 + let!(:user) do
  7 + user = Fabricate(:user)
  8 + app.watchers.create!(
  9 + :user_id => user.id
  10 + )
  11 + user.reload
  12 + end
  13 +
  14 + scenario 'log in watch a project and unwatch it' do
  15 + log_in user
  16 + click_on I18n.t('apps.show.unwatch')
  17 + expect(page).to have_content(I18n.t('apps.index.no_apps'))
  18 + end
  19 +
  20 +end
spec/controllers/apps_controller_spec.rb
@@ -5,11 +5,37 @@ describe AppsController do @@ -5,11 +5,37 @@ describe AppsController do
5 it_requires_authentication 5 it_requires_authentication
6 it_requires_admin_privileges :for => {:new => :get, :edit => :get, :create => :post, :update => :put, :destroy => :delete} 6 it_requires_admin_privileges :for => {:new => :get, :edit => :get, :create => :post, :update => :put, :destroy => :delete}
7 7
  8 + let(:admin) { Fabricate(:admin) }
  9 + let(:user) { Fabricate(:user) }
  10 + let(:watcher) { Fabricate(:user_watcher, :app => app, :user => user) }
  11 + let(:unwatched_app) { Fabricate(:app) }
  12 + let(:app) { unwatched_app }
  13 + let(:watched_app1) do
  14 + a = Fabricate(:app)
  15 + Fabricate(:user_watcher, :user => user, :app => a)
  16 + a
  17 + end
  18 + let(:watched_app2) do
  19 + a = Fabricate(:app)
  20 + Fabricate(:user_watcher, :user => user, :app => a)
  21 + a
  22 + end
  23 + let(:err) do
  24 + Fabricate(:err, :problem => problem)
  25 + end
  26 + let(:notice) do
  27 + Fabricate(:notice, :err => err)
  28 + end
  29 + let(:problem) do
  30 + Fabricate(:problem, :app => app)
  31 + end
  32 + let(:problem_resolved) { Fabricate(:problem_resolved, :app => app) }
  33 +
8 describe "GET /apps" do 34 describe "GET /apps" do
9 context 'when logged in as an admin' do 35 context 'when logged in as an admin' do
10 it 'finds all apps' do 36 it 'finds all apps' do
11 - sign_in Fabricate(:admin)  
12 - 3.times { Fabricate(:app) } 37 + sign_in admin
  38 + unwatched_app && watched_app1 && watched_app2
13 get :index 39 get :index
14 controller.apps.entries.should == App.all.sort.entries 40 controller.apps.entries.should == App.all.sort.entries
15 end 41 end
@@ -17,12 +43,8 @@ describe AppsController do @@ -17,12 +43,8 @@ describe AppsController do
17 43
18 context 'when logged in as a regular user' do 44 context 'when logged in as a regular user' do
19 it 'finds apps the user is watching' do 45 it 'finds apps the user is watching' do
20 - sign_in(user = Fabricate(:user))  
21 - unwatched_app = Fabricate(:app)  
22 - watched_app1 = Fabricate(:app)  
23 - watched_app2 = Fabricate(:app)  
24 - Fabricate(:user_watcher, :user => user, :app => watched_app1)  
25 - Fabricate(:user_watcher, :user => user, :app => watched_app2) 46 + sign_in(user)
  47 + watched_app1 && watched_app2 && unwatched_app
26 get :index 48 get :index
27 controller.apps.should include(watched_app1, watched_app2) 49 controller.apps.should include(watched_app1, watched_app2)
28 controller.apps.should_not include(unwatched_app) 50 controller.apps.should_not include(unwatched_app)
@@ -33,61 +55,56 @@ describe AppsController do @@ -33,61 +55,56 @@ describe AppsController do
33 describe "GET /apps/:id" do 55 describe "GET /apps/:id" do
34 context 'logged in as an admin' do 56 context 'logged in as an admin' do
35 before(:each) do 57 before(:each) do
36 - @user = Fabricate(:admin)  
37 - sign_in @user  
38 - @app = Fabricate(:app)  
39 - @problem = Fabricate(:notice, :err => Fabricate(:err, :problem => Fabricate(:problem, :app => @app))).problem 58 + sign_in admin
40 end 59 end
41 60
42 it 'finds the app' do 61 it 'finds the app' do
43 - get :show, :id => @app.id  
44 - controller.app.should == @app 62 + get :show, :id => app.id
  63 + controller.app.should == app
45 end 64 end
46 65
47 it "should not raise errors for app with err without notices" do 66 it "should not raise errors for app with err without notices" do
48 - Fabricate(:err, :problem => Fabricate(:problem, :app => @app))  
49 - lambda { get :show, :id => @app.id }.should_not raise_error 67 + err
  68 + lambda { get :show, :id => app.id }.should_not raise_error
50 end 69 end
51 70
52 it "should list atom feed successfully" do 71 it "should list atom feed successfully" do
53 - get :show, :id => @app.id, :format => "atom" 72 + get :show, :id => app.id, :format => "atom"
54 response.should be_success 73 response.should be_success
55 end 74 end
56 75
57 context "pagination" do 76 context "pagination" do
58 before(:each) do 77 before(:each) do
59 - 35.times { Fabricate(:err, :problem => Fabricate(:problem, :app => @app)) } 78 + 35.times { Fabricate(:err, :problem => Fabricate(:problem, :app => app)) }
60 end 79 end
61 80
62 it "should have default per_page value for user" do 81 it "should have default per_page value for user" do
63 - get :show, :id => @app.id 82 + get :show, :id => app.id
64 controller.problems.to_a.size.should == User::PER_PAGE 83 controller.problems.to_a.size.should == User::PER_PAGE
65 end 84 end
66 85
67 it "should be able to override default per_page value" do 86 it "should be able to override default per_page value" do
68 - @user.update_attribute :per_page, 10  
69 - get :show, :id => @app.id 87 + admin.update_attribute :per_page, 10
  88 + get :show, :id => app.id
70 controller.problems.to_a.size.should == 10 89 controller.problems.to_a.size.should == 10
71 end 90 end
72 end 91 end
73 92
74 context 'with resolved errors' do 93 context 'with resolved errors' do
75 before(:each) do 94 before(:each) do
76 - resolved_problem = Fabricate(:problem, :app => @app)  
77 - Fabricate(:notice, :err => Fabricate(:err, :problem => resolved_problem))  
78 - resolved_problem.resolve! 95 + problem_resolved && problem
79 end 96 end
80 97
81 context 'and no params' do 98 context 'and no params' do
82 it 'shows only unresolved problems' do 99 it 'shows only unresolved problems' do
83 - get :show, :id => @app.id 100 + get :show, :id => app.id
84 controller.problems.size.should == 1 101 controller.problems.size.should == 1
85 end 102 end
86 end 103 end
87 104
88 context 'and all_problems=true params' do 105 context 'and all_problems=true params' do
89 it 'shows all errors' do 106 it 'shows all errors' do
90 - get :show, :id => @app.id, :all_errs => true 107 + get :show, :id => app.id, :all_errs => true
91 controller.problems.size.should == 2 108 controller.problems.size.should == 2
92 end 109 end
93 end 110 end
@@ -97,41 +114,41 @@ describe AppsController do @@ -97,41 +114,41 @@ describe AppsController do
97 before(:each) do 114 before(:each) do
98 environments = ['production', 'test', 'development', 'staging'] 115 environments = ['production', 'test', 'development', 'staging']
99 20.times do |i| 116 20.times do |i|
100 - Fabricate(:problem, :app => @app, :environment => environments[i % environments.length]) 117 + Fabricate(:problem, :app => app, :environment => environments[i % environments.length])
101 end 118 end
102 end 119 end
103 120
104 context 'no params' do 121 context 'no params' do
105 it 'shows errs for all environments' do 122 it 'shows errs for all environments' do
106 - get :show, :id => @app.id  
107 - controller.problems.size.should == 21 123 + get :show, :id => app.id
  124 + controller.problems.size.should == 20
108 end 125 end
109 end 126 end
110 127
111 context 'environment production' do 128 context 'environment production' do
112 it 'shows errs for just production' do 129 it 'shows errs for just production' do
113 - get :show, :id => @app.id, :environment => 'production'  
114 - controller.problems.size.should == 6 130 + get :show, :id => app.id, :environment => 'production'
  131 + controller.problems.size.should == 5
115 end 132 end
116 end 133 end
117 134
118 context 'environment staging' do 135 context 'environment staging' do
119 it 'shows errs for just staging' do 136 it 'shows errs for just staging' do
120 - get :show, :id => @app.id, :environment => 'staging' 137 + get :show, :id => app.id, :environment => 'staging'
121 controller.problems.size.should == 5 138 controller.problems.size.should == 5
122 end 139 end
123 end 140 end
124 141
125 context 'environment development' do 142 context 'environment development' do
126 it 'shows errs for just development' do 143 it 'shows errs for just development' do
127 - get :show, :id => @app.id, :environment => 'development' 144 + get :show, :id => app.id, :environment => 'development'
128 controller.problems.size.should == 5 145 controller.problems.size.should == 5
129 end 146 end
130 end 147 end
131 148
132 context 'environment test' do 149 context 'environment test' do
133 it 'shows errs for just test' do 150 it 'shows errs for just test' do
134 - get :show, :id => @app.id, :environment => 'test' 151 + get :show, :id => app.id, :environment => 'test'
135 controller.problems.size.should == 5 152 controller.problems.size.should == 5
136 end 153 end
137 end 154 end
@@ -140,9 +157,7 @@ describe AppsController do @@ -140,9 +157,7 @@ describe AppsController do
140 157
141 context 'logged in as a user' do 158 context 'logged in as a user' do
142 it 'finds the app if the user is watching it' do 159 it 'finds the app if the user is watching it' do
143 - user = Fabricate(:user)  
144 - app = Fabricate(:app)  
145 - watcher = Fabricate(:user_watcher, :app => app, :user => user) 160 + watcher
146 sign_in user 161 sign_in user
147 get :show, :id => app.id 162 get :show, :id => app.id
148 controller.app.should == app 163 controller.app.should == app
@@ -160,7 +175,7 @@ describe AppsController do @@ -160,7 +175,7 @@ describe AppsController do
160 175
161 context 'logged in as an admin' do 176 context 'logged in as an admin' do
162 before do 177 before do
163 - sign_in Fabricate(:admin) 178 + sign_in admin
164 end 179 end
165 180
166 describe "GET /apps/new" do 181 describe "GET /apps/new" do
@@ -345,6 +360,34 @@ describe AppsController do @@ -345,6 +360,34 @@ describe AppsController do
345 end 360 end
346 end 361 end
347 362
  363 + describe "POST /apps/:id/regenerate_api_key" do
  364 +
  365 + context "like watcher" do
  366 + before do
  367 + sign_in watcher.user
  368 + end
  369 +
  370 + it 'redirect to root with flash error' do
  371 + post :regenerate_api_key, :id => 'foo'
  372 + expect(request).to redirect_to root_path
  373 + end
  374 +
  375 + end
  376 +
  377 + context "like admin" do
  378 + before do
  379 + sign_in admin
  380 + end
  381 +
  382 + it 'redirect_to app view' do
  383 + expect do
  384 + post :regenerate_api_key, :id => app.id
  385 + expect(request).to redirect_to edit_app_path(app)
  386 + end.to change { app.api_key }
  387 + end
  388 + end
  389 +
  390 + end
348 391
349 end 392 end
350 393
spec/fabricators/err_fabricator.rb
@@ -21,3 +21,4 @@ Fabricator :backtrace_line do @@ -21,3 +21,4 @@ Fabricator :backtrace_line do
21 file { "/path/to/file/#{SecureRandom.hex(4)}.rb" } 21 file { "/path/to/file/#{SecureRandom.hex(4)}.rb" }
22 method(:method) { ActiveSupport.methods.shuffle.first } 22 method(:method) { ActiveSupport.methods.shuffle.first }
23 end 23 end
  24 +
spec/fabricators/problem_fabricator.rb
@@ -21,4 +21,10 @@ Fabricator(:problem_with_errs, :from => :problem) do @@ -21,4 +21,10 @@ Fabricator(:problem_with_errs, :from => :problem) do
21 } 21 }
22 end 22 end
23 23
24 - 24 +Fabricator(:problem_resolved, :from => :problem) do
  25 + after_create do |pr|
  26 + Fabricate(:notice,
  27 + :err => Fabricate(:err, :problem => pr))
  28 + pr.resolve!
  29 + end
  30 +end