diff --git a/.gitignore b/.gitignore index b14ef0756..3d0bb1b25 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,7 @@ config/initializers/token.rb config/initializers/super_admin.rb doc/*.svg config/france_connect.yml +config/github_secrets.yml config/initializers/mailjet.rb config/fog_credentials.yml uploads/* diff --git a/app/controllers/administrations/omniauth_callbacks_controller.rb b/app/controllers/administrations/omniauth_callbacks_controller.rb new file mode 100644 index 000000000..71910756f --- /dev/null +++ b/app/controllers/administrations/omniauth_callbacks_controller.rb @@ -0,0 +1,16 @@ +class Administrations::OmniauthCallbacksController < Devise::OmniauthCallbacksController + def github + administration = Administration.from_omniauth(request.env["omniauth.auth"]) + if administration.present? + sign_in administration + redirect_to administrations_path + else + flash[:alert] = "Compte GitHub non autorisé" + redirect_to root_path + end + end + + def failure + redirect_to root_path + end +end diff --git a/app/models/administration.rb b/app/models/administration.rb index bab810519..f19ea8226 100644 --- a/app/models/administration.rb +++ b/app/models/administration.rb @@ -1,5 +1,9 @@ class Administration < ActiveRecord::Base # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable - devise :database_authenticatable, :rememberable, :trackable, :validatable + devise :database_authenticatable, :rememberable, :trackable, :validatable, :omniauthable, omniauth_providers: [:github] + + def self.from_omniauth(params) + find_by(email: params["info"]["email"]) + end end diff --git a/config/deploy.rb b/config/deploy.rb index 843687779..5e6b92153 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -65,6 +65,7 @@ set :shared_paths, [ "config/unicorn.rb", "config/initializers/raven.rb", 'config/france_connect.yml', + 'config/github_secrets.yml', 'config/initializers/mailjet.rb', 'config/initializers/storage_url.rb' ] diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 60f55f640..a12c61265 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -232,7 +232,10 @@ Devise.setup do |config| # ==> OmniAuth # Add a new OmniAuth provider. Check the wiki for more information on setting # up on your models and hooks. - # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo' + if !Rails.env.test? + github_secrets = YAML::load_file(File.join(__dir__, '../github_secrets.yml')) + config.omniauth :github, github_secrets['client_id'], github_secrets['client_secret'], scope: 'user:email' + end # ==> Warden configuration # If you want to use other strategies, that are not supported by Devise, or diff --git a/config/routes.rb b/config/routes.rb index cfbd00c09..e74b2385c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,7 +1,9 @@ Rails.application.routes.draw do get "/ping" => "ping#index", :constraints => {:ip => /127.0.0.1/} - devise_for :administrations, skip: [:password, :registrations] + devise_for :administrations, + skip: [:password, :registrations], + controllers: { omniauth_callbacks: 'administrations/omniauth_callbacks' } devise_for :administrateurs, controllers: { sessions: 'administrateurs/sessions' diff --git a/spec/controllers/administrations/omniauth_callbacks_controller_spec.rb b/spec/controllers/administrations/omniauth_callbacks_controller_spec.rb new file mode 100644 index 000000000..b037cb6d3 --- /dev/null +++ b/spec/controllers/administrations/omniauth_callbacks_controller_spec.rb @@ -0,0 +1,38 @@ +require 'spec_helper' + +describe Administrations::OmniauthCallbacksController, type: :controller do + before(:each) do + @request.env["devise.mapping"] = Devise.mappings[:administration] + end + + describe 'POST #github' do + let(:params) { { "info" => { "email" => email } } } + before do + controller.stub(:sign_in).and_return true + @request.env["omniauth.auth"] = params + end + subject { post :github } + + context 'with an authorized email' do + let(:email) { "ivan@tps.fr" } + let(:administration) { create(:administration, email: email) } + before { administration } + + it { is_expected.to redirect_to(administrations_path) } + it do + expect(controller).to receive(:sign_in).with(administration) + subject + end + end + + context 'with an unauthorized email' do + let(:email) { "michel@tps.fr" } + + it { is_expected.to redirect_to(root_path) } + it do + expect(controller).to_not receive(:sign_in) + subject + end + end + end +end