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 80 end
81 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 88 protected
84 89  
85 90 def initialize_subclassed_issue_tracker
... ...
app/models/app.rb
... ... @@ -170,6 +170,10 @@ class App
170 170 Errbit::Config.per_app_email_at_notices ? super : Errbit::Config.email_at_notices
171 171 end
172 172  
  173 + def regenerate_api_key!
  174 + set(:api_key, SecureRandom.hex)
  175 + end
  176 +
173 177 protected
174 178  
175 179 def store_cached_attributes_on_problems
... ...
app/views/apps/_fields.html.haml
... ... @@ -5,6 +5,10 @@
5 5 = f.text_field :name
6 6  
7 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 12 = f.label :repository_branch
9 13 = f.text_field :repository_branch, :placeholder => "master"
10 14 %div
... ...
config/locales/en.yml
... ... @@ -81,6 +81,8 @@ en:
81 81 new_app: Add a New App
82 82 no_apps: 'No apps here.'
83 83 click_to_create: 'Click here to create your first one'
  84 + fields:
  85 + regenerate_api_key: "Regenerate API key"
84 86 show:
85 87 all_deploys: "All Deploys (%{count})"
86 88 all_errs: all errs
... ... @@ -100,7 +102,6 @@ en:
100 102 no_error_yet: "No errs have been caught yet, make sure you setup your app"
101 103 no_watcher: "Sadly, no one is watching this app"
102 104 repository: Repository
103   - repository: Repository
104 105 revision: Revision
105 106 search_placeholder: 'Search for issues'
106 107 show_hide: "(show/hide)"
... ... @@ -110,3 +111,4 @@ en:
110 111 watchers: Watchers
111 112 when: When
112 113 who: Who
  114 +
... ...
config/routes.rb
... ... @@ -39,6 +39,9 @@ Errbit::Application.routes.draw do
39 39 end
40 40 resources :deploys, :only => [:index]
41 41 resources :watchers, :only => [:destroy]
  42 + member do
  43 + post :regenerate_api_key
  44 + end
42 45 end
43 46  
44 47 namespace :api do
... ...
spec/acceptance/acceptance_helper.rb
... ... @@ -17,3 +17,10 @@ def mock_auth(user = "test_user", token = "abcdef")
17 17 }
18 18 )
19 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 @@
  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   -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 @@
  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 5 it_requires_authentication
6 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 34 describe "GET /apps" do
9 35 context 'when logged in as an admin' do
10 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 39 get :index
14 40 controller.apps.entries.should == App.all.sort.entries
15 41 end
... ... @@ -17,12 +43,8 @@ describe AppsController do
17 43  
18 44 context 'when logged in as a regular user' do
19 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 48 get :index
27 49 controller.apps.should include(watched_app1, watched_app2)
28 50 controller.apps.should_not include(unwatched_app)
... ... @@ -33,61 +55,56 @@ describe AppsController do
33 55 describe "GET /apps/:id" do
34 56 context 'logged in as an admin' do
35 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 59 end
41 60  
42 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 64 end
46 65  
47 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 69 end
51 70  
52 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 73 response.should be_success
55 74 end
56 75  
57 76 context "pagination" do
58 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 79 end
61 80  
62 81 it "should have default per_page value for user" do
63   - get :show, :id => @app.id
  82 + get :show, :id => app.id
64 83 controller.problems.to_a.size.should == User::PER_PAGE
65 84 end
66 85  
67 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 89 controller.problems.to_a.size.should == 10
71 90 end
72 91 end
73 92  
74 93 context 'with resolved errors' do
75 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 96 end
80 97  
81 98 context 'and no params' do
82 99 it 'shows only unresolved problems' do
83   - get :show, :id => @app.id
  100 + get :show, :id => app.id
84 101 controller.problems.size.should == 1
85 102 end
86 103 end
87 104  
88 105 context 'and all_problems=true params' do
89 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 108 controller.problems.size.should == 2
92 109 end
93 110 end
... ... @@ -97,41 +114,41 @@ describe AppsController do
97 114 before(:each) do
98 115 environments = ['production', 'test', 'development', 'staging']
99 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 118 end
102 119 end
103 120  
104 121 context 'no params' do
105 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 125 end
109 126 end
110 127  
111 128 context 'environment production' do
112 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 132 end
116 133 end
117 134  
118 135 context 'environment staging' do
119 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 138 controller.problems.size.should == 5
122 139 end
123 140 end
124 141  
125 142 context 'environment development' do
126 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 145 controller.problems.size.should == 5
129 146 end
130 147 end
131 148  
132 149 context 'environment test' do
133 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 152 controller.problems.size.should == 5
136 153 end
137 154 end
... ... @@ -140,9 +157,7 @@ describe AppsController do
140 157  
141 158 context 'logged in as a user' do
142 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 161 sign_in user
147 162 get :show, :id => app.id
148 163 controller.app.should == app
... ... @@ -160,7 +175,7 @@ describe AppsController do
160 175  
161 176 context 'logged in as an admin' do
162 177 before do
163   - sign_in Fabricate(:admin)
  178 + sign_in admin
164 179 end
165 180  
166 181 describe "GET /apps/new" do
... ... @@ -345,6 +360,34 @@ describe AppsController do
345 360 end
346 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 392 end
350 393  
... ...
spec/fabricators/err_fabricator.rb
... ... @@ -21,3 +21,4 @@ Fabricator :backtrace_line do
21 21 file { "/path/to/file/#{SecureRandom.hex(4)}.rb" }
22 22 method(:method) { ActiveSupport.methods.shuffle.first }
23 23 end
  24 +
... ...
spec/fabricators/problem_fabricator.rb
... ... @@ -21,4 +21,10 @@ Fabricator(:problem_with_errs, :from => :problem) do
21 21 }
22 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
... ...