From 400beb72c542312e3009dae8a7cf4e3e0b8bf1e1 Mon Sep 17 00:00:00 2001 From: Nathan Broadbent Date: Sat, 2 Jun 2012 20:04:38 +1200 Subject: [PATCH] Added 'repo' scope for OAuth, for access to issues. Added ability to link and unlink github account. --- app/assets/stylesheets/errbit.css | 2 +- app/assets/stylesheets/images/icons/unlink_github.png | Bin 0 -> 2069 bytes app/controllers/users/omniauth_callbacks_controller.rb | 27 ++++++++++++++++++++++++--- app/controllers/users_controller.rb | 7 ++++++- app/models/user.rb | 7 +------ app/views/shared/_link_github_account.html.haml | 5 +++++ app/views/users/edit.html.haml | 8 +++++--- app/views/users/show.html.haml | 8 ++++---- config/initializers/devise.rb | 2 +- config/routes.rb | 6 +++++- spec/models/user_spec.rb | 9 --------- 11 files changed, 52 insertions(+), 29 deletions(-) create mode 100644 app/assets/stylesheets/images/icons/unlink_github.png create mode 100644 app/views/shared/_link_github_account.html.haml diff --git a/app/assets/stylesheets/errbit.css b/app/assets/stylesheets/errbit.css index da91296..90a65a7 100644 --- a/app/assets/stylesheets/errbit.css +++ b/app/assets/stylesheets/errbit.css @@ -225,7 +225,7 @@ a.action { float: right; font-size: 0.9em;} } #action-bar span.github a { background: url(images/icons/github.png) no-repeat 6px 5px; } - +#action-bar span.unlink_github a { background: url(images/icons/unlink_github.png) no-repeat 6px 5px; } /* Content */ #content { diff --git a/app/assets/stylesheets/images/icons/unlink_github.png b/app/assets/stylesheets/images/icons/unlink_github.png new file mode 100644 index 0000000..06fd35a Binary files /dev/null and b/app/assets/stylesheets/images/icons/unlink_github.png differ diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb index 8c54131..f41fdd3 100644 --- a/app/controllers/users/omniauth_callbacks_controller.rb +++ b/app/controllers/users/omniauth_callbacks_controller.rb @@ -1,9 +1,30 @@ class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController def github - @user = User.find_for_github_oauth(request.env["omniauth.auth"]) + github_login = request.env["omniauth.auth"].extra.raw_info.login + github_token = request.env["omniauth.auth"].credentials.token + github_user = User.where(:github_login => github_login).first - if @user - flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Github" + # If user is already signed in, link github details to their account + if current_user + # ... unless a user is already registered with same github login + if github_user && github_user != current_user + flash[:error] = "User already registered with Github login '#{github_login}'" + redirect_to user_path(current_user) + else + # Add github details to current user + current_user.update_attributes( + :github_login => github_login, + :github_oauth_token => github_token + ) + flash[:success] = "Successfully linked Github account!" + redirect_to user_path(current_user) + end + + elsif github_user + # Store OAuth token + @user.update_attribute :github_oauth_token, request.env["omniauth.auth"].credentials.token + + flash[:success] = I18n.t "devise.omniauth_callbacks.success", :kind => "Github" sign_in_and_redirect @user, :event => :authentication else redirect_to new_user_session_path diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index a7d437b..37c520c 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -2,7 +2,7 @@ class UsersController < ApplicationController respond_to :html before_filter :require_admin!, :except => [:edit, :update] - before_filter :find_user, :only => [:show, :edit, :update, :destroy] + before_filter :find_user, :only => [:show, :edit, :update, :destroy, :unlink_github] before_filter :require_user_edit_priviledges, :only => [:edit, :update] def index @@ -59,6 +59,11 @@ class UsersController < ApplicationController redirect_to users_path end + def unlink_github + @user.update_attributes :github_login => nil, :github_oauth_token => nil + redirect_to user_path(@user) + end + protected def find_user diff --git a/app/models/user.rb b/app/models/user.rb index 1e118df..a3b3222 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -7,6 +7,7 @@ class User field :email field :github_login + field :github_oauth_token field :name field :admin, :type => Boolean, :default => false field :per_page, :type => Fixnum, :default => PER_PAGE @@ -39,12 +40,6 @@ class User apps.all.include?(app) end - def self.find_for_github_oauth(omniauth_env) - data = omniauth_env.extra.raw_info - - User.where(:github_login => data.login).first - end - def password_required? github_login.present? ? false : super end diff --git a/app/views/shared/_link_github_account.html.haml b/app/views/shared/_link_github_account.html.haml new file mode 100644 index 0000000..704e273 --- /dev/null +++ b/app/views/shared/_link_github_account.html.haml @@ -0,0 +1,5 @@ +- if Errbit::Config.github_authentication && user == current_user + - if user.github_login && user.github_oauth_token + %span.unlink_github= link_to "Unlink GitHub account", unlink_github_user_path(user), :method => :delete, :confirm => "Are you sure?" + - else + %span.github= link_to "Link GitHub account", user_omniauth_authorize_path(:github) diff --git a/app/views/users/edit.html.haml b/app/views/users/edit.html.haml index c0eb807..14a6883 100644 --- a/app/views/users/edit.html.haml +++ b/app/views/users/edit.html.haml @@ -1,8 +1,10 @@ - content_for :title, "Edit #{@user.name}" -- content_for :action_bar, link_to('cancel', user_path(@user), :class => 'button') +- content_for :action_bar do + = render :partial => 'shared/link_github_account', :locals => {:user => @user} + = link_to('cancel', user_path(@user), :class => 'button') = form_for @user, :html => {:autocomplete => "off"} do |f| = @user.errors.full_messages.to_sentence = render 'fields', :f => f - - %div.buttons= f.submit 'Update User' \ No newline at end of file + + %div.buttons= f.submit 'Update User' diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index 5d82144..3c3eef6 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -1,9 +1,12 @@ - content_for :title, @user.name - content_for :action_bar do + = render :partial => 'shared/link_github_account', :locals => {:user => @user} %span= link_to('Add a New User', new_user_path, :class => 'add') = link_to 'edit', edit_user_path(@user), :class => 'button' = link_to 'destroy', user_path(@user), :method => :delete, :confirm => 'Seriously?', :class => 'button' + + %table.single_user %tr %th Email @@ -14,12 +17,9 @@ %td.main= @user.username - if Errbit::Config.github_authentication && @user.github_login.present? %tr - %th GitHub + %th GitHub Login %td.main= link_to @user.github_login, "https://github.com/#{@user.github_login}" %tr - %th Token - %td= @user.authentication_token - %tr %th Admin? %td= @user.admin? ? 'Y' : 'N' %tr diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index a095edc..d5fdb78 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -119,7 +119,7 @@ Devise.setup do |config| # config.sign_out_all_scopes = false if Errbit::Config.github_authentication || Rails.env.test? - config.omniauth :github, Errbit::Config.github_client_id, Errbit::Config.github_secret + config.omniauth :github, Errbit::Config.github_client_id, Errbit::Config.github_secret, :scope => 'repo' end # ==> Navigation configuration diff --git a/config/routes.rb b/config/routes.rb index f6221e0..8adf1e9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -8,7 +8,11 @@ Errbit::Application.routes.draw do resources :notices, :only => [:show] resources :deploys, :only => [:show] - resources :users + resources :users do + member do + delete :unlink_github + end + end resources :errs, :only => [:index] do collection do post :destroy_several diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index a7f85ed..5d4dcc5 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -31,15 +31,6 @@ describe User do end end - describe '.find_for_github_oauth' do - let(:auth_hash) { Hashie::Mash.new(:provider => 'github', :extra => { :raw_info => { :login => 'nashby' } }) } - - it 'finds user by github login' do - user = Fabricate(:user, :github_login => 'nashby') - User.find_for_github_oauth(auth_hash).should == user - end - end - context 'Watchers' do it 'has many watchers' do -- libgit2 0.21.2