Commit 14a18a0c5a80cb7bedf5f2c13244d28eabc994ef
1 parent
400beb72
Exists in
master
and in
1 other branch
Refactored and wrote specs to cover GitHub integration. Renamed [gG]it[hH]ub => GitHub.
Showing
12 changed files
with
139 additions
and
53 deletions
Show diff stats
README.md
... | ... | @@ -258,10 +258,10 @@ Issue Trackers |
258 | 258 | * Project id is the identifier of your project, i.e. **awesomeapp** for project at https://mingle.example.com/projects/awesomeapp |
259 | 259 | * Card properties are comma separated key value pairs. You must specify a 'card_type', but anything else is optional. i.e. card_type = Defect, status = Open, priority = Essential |
260 | 260 | |
261 | -**Github Issues Integration** | |
261 | +**GitHub Issues Integration** | |
262 | 262 | |
263 | 263 | * For 'Account/Repository', the account will either be a username or organization. i.e. **errbit/errbit** |
264 | -* You will also need to provide your username and password for your Github account. | |
264 | +* You will also need to provide your username and password for your GitHub account. | |
265 | 265 | * (We'd really appreciate it if you wanted to help us implement OAuth instead!) |
266 | 266 | |
267 | 267 | |
... | ... | @@ -271,23 +271,23 @@ What if Errbit has an error? |
271 | 271 | Errbit will log it's own errors to an internal app named **Self.Errbit**. |
272 | 272 | The **Self.Errbit** app will be automatically created whenever the first error happens. |
273 | 273 | |
274 | -If your Errbit instance has logged an error, we would appreciate a bug report on Github Issues. | |
274 | +If your Errbit instance has logged an error, we would appreciate a bug report on GitHub Issues. | |
275 | 275 | You can post this manually at [https://github.com/errbit/errbit/issues](https://github.com/errbit/errbit/issues), |
276 | -or you can set up the Github Issues tracker for your **Self.Errbit** app: | |
276 | +or you can set up the GitHub Issues tracker for your **Self.Errbit** app: | |
277 | 277 | |
278 | 278 | 1. Go to the **Self.Errbit** app's edit page. If that app does not exist yet, go to the apps page and click **Add a new App** to create it. (You can also create it by running `rake airbrake:test`.) |
279 | 279 | |
280 | - 2. In the **Issue Tracker** section, click **Github Issues**. | |
280 | + 2. In the **Issue Tracker** section, click **GitHub Issues**. | |
281 | 281 | |
282 | 282 | 3. Fill in the **Account/Repository** field with **errbit/errbit**. |
283 | 283 | |
284 | 284 | 4. Fill in the **Username** field with your github username. |
285 | 285 | |
286 | - 5. If you are logged in on [Github](https://github.com), you can find your **API Token** on this page: [https://github.com/account/admin](https://github.com/account/admin). | |
286 | + 5. If you are logged in on [GitHub](https://github.com), you can find your **API Token** on this page: [https://github.com/account/admin](https://github.com/account/admin). | |
287 | 287 | |
288 | 288 | 6. Save the settings by clicking **Update App** (or **Add App**) |
289 | 289 | |
290 | - 7. You can now easily post bug reports to Github Issues by clicking the **Create Issue** button on a **Self.Errbit** error. | |
290 | + 7. You can now easily post bug reports to GitHub Issues by clicking the **Create Issue** button on a **Self.Errbit** error. | |
291 | 291 | |
292 | 292 | |
293 | 293 | TODO | ... | ... |
app/controllers/users/omniauth_callbacks_controller.rb
1 | 1 | class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController |
2 | 2 | def github |
3 | - github_login = request.env["omniauth.auth"].extra.raw_info.login | |
4 | - github_token = request.env["omniauth.auth"].credentials.token | |
3 | + github_login = env["omniauth.auth"].extra.raw_info.login | |
4 | + github_token = env["omniauth.auth"].credentials.token | |
5 | 5 | github_user = User.where(:github_login => github_login).first |
6 | 6 | |
7 | 7 | # If user is already signed in, link github details to their account |
8 | 8 | if current_user |
9 | 9 | # ... unless a user is already registered with same github login |
10 | 10 | if github_user && github_user != current_user |
11 | - flash[:error] = "User already registered with Github login '#{github_login}'" | |
12 | - redirect_to user_path(current_user) | |
11 | + flash[:error] = "User already registered with GitHub login '#{github_login}'" | |
13 | 12 | else |
14 | 13 | # Add github details to current user |
15 | 14 | current_user.update_attributes( |
16 | 15 | :github_login => github_login, |
17 | 16 | :github_oauth_token => github_token |
18 | 17 | ) |
19 | - flash[:success] = "Successfully linked Github account!" | |
20 | - redirect_to user_path(current_user) | |
18 | + flash[:success] = "Successfully linked GitHub account!" | |
21 | 19 | end |
22 | - | |
20 | + # User must have clicked 'link account' from their user page, so redirect there. | |
21 | + redirect_to user_path(current_user) | |
23 | 22 | elsif github_user |
24 | 23 | # Store OAuth token |
25 | - @user.update_attribute :github_oauth_token, request.env["omniauth.auth"].credentials.token | |
24 | + github_user.update_attribute :github_oauth_token, github_token | |
26 | 25 | |
27 | - flash[:success] = I18n.t "devise.omniauth_callbacks.success", :kind => "Github" | |
28 | - sign_in_and_redirect @user, :event => :authentication | |
26 | + flash[:success] = I18n.t "devise.omniauth_callbacks.success", :kind => "GitHub" | |
27 | + sign_in_and_redirect github_user, :event => :authentication | |
29 | 28 | else |
29 | + flash[:error] = "There are no authorized users with GitHub login '#{github_login}'. Please ask an administrator to register your user account." | |
30 | 30 | redirect_to new_user_session_path |
31 | 31 | end |
32 | 32 | end | ... | ... |
app/models/issue_trackers/github_issues_tracker.rb
... | ... | @@ -6,7 +6,7 @@ class IssueTrackers::GithubIssuesTracker < IssueTracker |
6 | 6 | :placeholder => "errbit/errbit from https://github.com/errbit/errbit" |
7 | 7 | }], |
8 | 8 | [:username, { |
9 | - :placeholder => "Your username on Github" | |
9 | + :placeholder => "Your username on GitHub" | |
10 | 10 | }], |
11 | 11 | [:password, { |
12 | 12 | :placeholder => "Password for your account" |
... | ... | @@ -15,7 +15,7 @@ class IssueTrackers::GithubIssuesTracker < IssueTracker |
15 | 15 | |
16 | 16 | def check_params |
17 | 17 | if Fields.detect {|f| self[f[0]].blank? } |
18 | - errors.add :base, 'You must specify your Github repository, username and password' | |
18 | + errors.add :base, 'You must specify your GitHub repository, username and password' | |
19 | 19 | end |
20 | 20 | end |
21 | 21 | |
... | ... | @@ -25,7 +25,7 @@ class IssueTrackers::GithubIssuesTracker < IssueTracker |
25 | 25 | issue = client.create_issue(project_id, issue_title(problem), body_template.result(binding).unpack('C*').pack('U*'), options = {}) |
26 | 26 | problem.update_attribute :issue_link, issue.html_url |
27 | 27 | rescue Octokit::Unauthorized |
28 | - raise IssueTrackers::AuthenticationError, "Could not authenticate with Github. Please check your username and password." | |
28 | + raise IssueTrackers::AuthenticationError, "Could not authenticate with GitHub. Please check your username and password." | |
29 | 29 | end |
30 | 30 | end |
31 | 31 | ... | ... |
app/views/users/show.html.haml
config/config.example.yml
... | ... | @@ -49,8 +49,8 @@ deployment: |
49 | 49 | user: deploy |
50 | 50 | deploy_to: /var/www/apps/errbit |
51 | 51 | |
52 | -# Github OAuth configuration | |
53 | -# If you want to allow authentication via Github, you will need to register | |
52 | +# GitHub OAuth configuration | |
53 | +# If you want to allow authentication via GitHub, you will need to register | |
54 | 54 | # your app at: https://github.com/settings/applications |
55 | 55 | # If you hosted Errbit at errbit.example.com, you would fill in: |
56 | 56 | # | ... | ... |
spec/acceptance/acceptance_helper.rb
... | ... | @@ -3,16 +3,17 @@ require 'capybara/rspec' |
3 | 3 | |
4 | 4 | OmniAuth.config.test_mode = true |
5 | 5 | |
6 | -RSpec.configure do |config| | |
7 | - config.before(:each) do | |
8 | - OmniAuth.config.mock_auth[:github] = Hashie::Mash.new( | |
9 | - 'provider' => 'github', | |
10 | - 'uid' => '1763', | |
11 | - 'extra' => { | |
12 | - 'raw_info' => { | |
13 | - 'login' => 'nashby' | |
14 | - } | |
6 | +def mock_auth(user = "test_user", token = "abcdef") | |
7 | + OmniAuth.config.mock_auth[:github] = Hashie::Mash.new( | |
8 | + 'provider' => 'github', | |
9 | + 'uid' => '1763', | |
10 | + 'extra' => { | |
11 | + 'raw_info' => { | |
12 | + 'login' => user | |
15 | 13 | } |
16 | - ) | |
17 | - end | |
14 | + }, | |
15 | + 'credentials' => { | |
16 | + 'token' => token | |
17 | + } | |
18 | + ) | |
18 | 19 | end | ... | ... |
spec/acceptance/login_spec.rb
... | ... | @@ -1,14 +0,0 @@ |
1 | -require 'acceptance/acceptance_helper' | |
2 | - | |
3 | -feature 'Log in' do | |
4 | - background do | |
5 | - Errbit::Config.stub(:github_authentication) { true } | |
6 | - Fabricate(:user, :github_login => 'nashby') | |
7 | - end | |
8 | - | |
9 | - scenario 'log in via GitHub' do | |
10 | - visit '/' | |
11 | - click_link 'Sign in with GitHub' | |
12 | - page.should have_content 'Successfully authorized from Github account' | |
13 | - end | |
14 | -end |
... | ... | @@ -0,0 +1,24 @@ |
1 | +require 'acceptance/acceptance_helper' | |
2 | + | |
3 | +feature 'Sign in with GitHub' do | |
4 | + background do | |
5 | + Errbit::Config.stub(:github_authentication) { true } | |
6 | + Fabricate(:user, :github_login => 'nashby') | |
7 | + end | |
8 | + | |
9 | + scenario 'log in via GitHub with recognized user' do | |
10 | + mock_auth('nashby') | |
11 | + | |
12 | + visit '/' | |
13 | + click_link 'Sign in with GitHub' | |
14 | + page.should have_content 'Successfully authorized from GitHub account' | |
15 | + end | |
16 | + | |
17 | + scenario 'reject unrecognized user if authenticating via GitHub' do | |
18 | + mock_auth('unknown_user') | |
19 | + | |
20 | + visit '/' | |
21 | + click_link 'Sign in with GitHub' | |
22 | + page.should have_content 'There are no authorized users with GitHub login' | |
23 | + end | |
24 | +end | ... | ... |
spec/controllers/users/omniauth_callbacks_controller_spec.rb
0 → 100644
... | ... | @@ -0,0 +1,42 @@ |
1 | +require 'spec_helper' | |
2 | + | |
3 | +describe Users::OmniauthCallbacksController do | |
4 | + | |
5 | + def stub_env_for_github_omniauth(login, token = nil) | |
6 | + # This a Devise specific thing for functional tests. See https://github.com/plataformatec/devise/issues/closed#issue/608 | |
7 | + request.env["devise.mapping"] = Devise.mappings[:user] | |
8 | + env = { | |
9 | + "omniauth.auth" => Hashie::Mash.new( | |
10 | + :provider => 'github', | |
11 | + :extra => { :raw_info => { :login => login }}, | |
12 | + :credentials => { :token => token } | |
13 | + ) | |
14 | + } | |
15 | + @controller.stub!(:env).and_return(env) | |
16 | + end | |
17 | + | |
18 | + context 'Linking a GitHub account to a signed in user' do | |
19 | + before do | |
20 | + sign_in @user = Fabricate(:user) | |
21 | + end | |
22 | + | |
23 | + it "should show an error if another user already has that github login" do | |
24 | + Fabricate(:user, :github_login => "existing_user") | |
25 | + stub_env_for_github_omniauth("existing_user") | |
26 | + get :github | |
27 | + | |
28 | + request.flash[:error].should include('already registered') | |
29 | + response.should redirect_to(user_path(@user)) | |
30 | + end | |
31 | + | |
32 | + it "should link an authorized GitHub account" do | |
33 | + stub_env_for_github_omniauth("new_user") | |
34 | + get :github | |
35 | + | |
36 | + request.flash[:success].should include('Successfully linked') | |
37 | + response.should redirect_to(user_path(@user)) | |
38 | + end | |
39 | + end | |
40 | + | |
41 | + # See spec/acceptance/sign_in_with_github_spec.rb for 'Signing in with github' integration tests. | |
42 | +end | ... | ... |
spec/models/issue_trackers/github_issues_tracker_spec.rb
1 | 1 | require 'spec_helper' |
2 | 2 | |
3 | 3 | describe IssueTrackers::GithubIssuesTracker do |
4 | - it "should create an issue on Github Issues with problem params, and set issue link for problem" do | |
4 | + it "should create an issue on GitHub Issues with problem params, and set issue link for problem" do | |
5 | 5 | notice = Fabricate :notice |
6 | 6 | tracker = Fabricate :github_issues_tracker, :app => notice.app |
7 | 7 | problem = notice.problem | ... | ... |
spec/spec_helper.rb
spec/views/users/show.html.haml_spec.rb
... | ... | @@ -5,11 +5,12 @@ describe 'users/show.html.haml' do |
5 | 5 | user = stub_model(User, :created_at => Time.now) |
6 | 6 | end |
7 | 7 | |
8 | - context 'with github auth' do | |
9 | - before do | |
10 | - Errbit::Config.stub(:github_authentication) { true } | |
11 | - end | |
8 | + before do | |
9 | + Errbit::Config.stub(:github_authentication) { true } | |
10 | + controller.stub(:current_user) { Fabricate(:user) } | |
11 | + end | |
12 | 12 | |
13 | + context 'with GitHub authentication' do | |
13 | 14 | it 'shows github login' do |
14 | 15 | user.github_login = 'test_user' |
15 | 16 | assign :user, user |
... | ... | @@ -25,4 +26,35 @@ describe 'users/show.html.haml' do |
25 | 26 | rendered.should_not match(/GitHub/) |
26 | 27 | end |
27 | 28 | end |
29 | + | |
30 | + context "Linking GitHub account" do | |
31 | + context 'viewing another user page' do | |
32 | + it "doesn't show and github linking buttons if user is not current user" do | |
33 | + assign :user, user | |
34 | + render | |
35 | + view.content_for(:action_bar).should_not include('Link GitHub account') | |
36 | + view.content_for(:action_bar).should_not include('Unlink GitHub account') | |
37 | + end | |
38 | + end | |
39 | + | |
40 | + context 'viewing own user page' do | |
41 | + before do | |
42 | + @user = Fabricate(:user) | |
43 | + controller.stub!(:current_user).and_return(@user) | |
44 | + assign :user, @user | |
45 | + end | |
46 | + | |
47 | + it 'shows link github button when no login or token' do | |
48 | + render | |
49 | + view.content_for(:action_bar).should include('Link GitHub account') | |
50 | + end | |
51 | + | |
52 | + it 'shows unlink github button when login and token' do | |
53 | + @user.github_login = 'test_user' | |
54 | + @user.github_oauth_token = 'abcdef' | |
55 | + render | |
56 | + view.content_for(:action_bar).should include('Unlink GitHub account') | |
57 | + end | |
58 | + end | |
59 | + end | |
28 | 60 | end | ... | ... |