From 46b14e97ed78a81550448d1be29fd76f95fd433a Mon Sep 17 00:00:00 2001 From: Mathieu Magnin Date: Wed, 20 Dec 2017 11:46:17 +0100 Subject: [PATCH 1/6] [Fix #1096] Add omniauth gem to connect with Github --- Gemfile | 1 + Gemfile.lock | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/Gemfile b/Gemfile index fec62ee7f..00e2af737 100644 --- a/Gemfile +++ b/Gemfile @@ -44,6 +44,7 @@ gem 'unicode_utils' # Gestion des comptes utilisateurs gem 'devise' gem 'openid_connect' +gem 'omniauth-github' gem 'rest-client' diff --git a/Gemfile.lock b/Gemfile.lock index 994f844f5..4e7551cd9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -357,6 +357,7 @@ GEM url_safe_base64 jsonapi (0.1.1.beta2) json (~> 1.8) + jwt (1.5.6) kaminari (0.17.0) actionpack (>= 3.0.0) activesupport (>= 3.0.0) @@ -396,6 +397,7 @@ GEM mini_portile2 (2.3.0) minitest (5.10.3) multi_json (1.12.1) + multi_xml (0.6.0) multipart-post (2.0.0) mustermann (1.0.1) nenv (0.3.0) @@ -406,6 +408,21 @@ GEM notiffany (0.1.1) nenv (~> 0.1) shellany (~> 0.0) + oauth2 (1.4.0) + faraday (>= 0.8, < 0.13) + jwt (~> 1.0) + multi_json (~> 1.3) + multi_xml (~> 0.5) + rack (>= 1.2, < 3) + omniauth (1.7.1) + hashie (>= 3.4.6, < 3.6.0) + rack (>= 1.6.2, < 3) + omniauth-github (1.3.0) + omniauth (~> 1.5) + omniauth-oauth2 (>= 1.4.0, < 2.0) + omniauth-oauth2 (1.5.0) + oauth2 (~> 1.1) + omniauth (~> 1.2) open4 (1.3.4) openid_connect (0.12.0) activemodel @@ -720,6 +737,7 @@ DEPENDENCIES mailjet maruku mina! + omniauth-github openid_connect openstack pg From 7c0fdbc9f83c36f6b6b8f9cc260d6fbd4e7b4027 Mon Sep 17 00:00:00 2001 From: Mathieu Magnin Date: Wed, 20 Dec 2017 15:27:33 +0100 Subject: [PATCH 2/6] [Fix #1096] Github Oauth --- .gitignore | 1 + .../omniauth_callbacks_controller.rb | 16 ++++++++ app/models/administration.rb | 6 ++- config/deploy.rb | 1 + config/initializers/devise.rb | 5 ++- config/routes.rb | 4 +- .../omniauth_callbacks_controller_spec.rb | 38 +++++++++++++++++++ 7 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 app/controllers/administrations/omniauth_callbacks_controller.rb create mode 100644 spec/controllers/administrations/omniauth_callbacks_controller_spec.rb 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 From 4990595430803bceaab79ce33432be45ea40525c Mon Sep 17 00:00:00 2001 From: Mathieu Magnin Date: Thu, 21 Dec 2017 11:41:44 +0100 Subject: [PATCH 3/6] [Fix #1096] Sign in with GitHub page --- app/assets/stylesheets/new_design/flex.scss | 4 ++++ app/assets/stylesheets/new_design/super_admin.scss | 11 +++++++++++ .../administrations/sessions_controller.rb | 11 +++++++++++ app/views/administrations/index.html.haml | 2 +- app/views/administrations/sessions/new.html.haml | 6 ++++++ config/routes.rb | 8 ++++++-- 6 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 app/assets/stylesheets/new_design/super_admin.scss create mode 100644 app/controllers/administrations/sessions_controller.rb create mode 100644 app/views/administrations/sessions/new.html.haml diff --git a/app/assets/stylesheets/new_design/flex.scss b/app/assets/stylesheets/new_design/flex.scss index 43416c333..0689c004c 100644 --- a/app/assets/stylesheets/new_design/flex.scss +++ b/app/assets/stylesheets/new_design/flex.scss @@ -16,4 +16,8 @@ &.justify-between { justify-content: space-between; } + + &.justify-center { + justify-content: center; + } } diff --git a/app/assets/stylesheets/new_design/super_admin.scss b/app/assets/stylesheets/new_design/super_admin.scss new file mode 100644 index 000000000..949f1aa4d --- /dev/null +++ b/app/assets/stylesheets/new_design/super_admin.scss @@ -0,0 +1,11 @@ +@import "constants"; + +.super-admin { + margin-top: 40px; + text-align: center; + + h2 { + font-size: 24px; + margin-bottom: 4 * $default-spacer; + } +} diff --git a/app/controllers/administrations/sessions_controller.rb b/app/controllers/administrations/sessions_controller.rb new file mode 100644 index 000000000..5c1c66000 --- /dev/null +++ b/app/controllers/administrations/sessions_controller.rb @@ -0,0 +1,11 @@ +class Administrations::SessionsController < ApplicationController + layout "new_application" + + def new + end + + def destroy + sign_out :administration if administration_signed_in? + redirect_to root_path + end +end diff --git a/app/views/administrations/index.html.haml b/app/views/administrations/index.html.haml index c4e7eefc5..869242426 100644 --- a/app/views/administrations/index.html.haml +++ b/app/views/administrations/index.html.haml @@ -13,4 +13,4 @@ %br .text-center - = link_to 'Deconnexion', '/administrations/sign_out', method: :delete + = link_to 'Deconnexion', administrations_sign_out_path, method: :delete diff --git a/app/views/administrations/sessions/new.html.haml b/app/views/administrations/sessions/new.html.haml new file mode 100644 index 000000000..8ed5fb4d9 --- /dev/null +++ b/app/views/administrations/sessions/new.html.haml @@ -0,0 +1,6 @@ +.super-admin.flex.justify-center + %div + %h2 Espace Admin + = link_to administration_github_omniauth_authorize_path, class: "button large" do + %span.icon.lock + Connexion avec GitHub diff --git a/config/routes.rb b/config/routes.rb index e74b2385c..275c8431c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,8 +2,10 @@ Rails.application.routes.draw do get "/ping" => "ping#index", :constraints => {:ip => /127.0.0.1/} devise_for :administrations, - skip: [:password, :registrations], - controllers: { omniauth_callbacks: 'administrations/omniauth_callbacks' } + skip: [:password, :registrations, :sessions], + controllers: { + omniauth_callbacks: 'administrations/omniauth_callbacks' + } devise_for :administrateurs, controllers: { sessions: 'administrateurs/sessions' @@ -44,6 +46,8 @@ Rails.application.routes.draw do get 'admin' => 'admin#index' get 'backoffice' => 'backoffice#index' + get 'administrations/sign_in' => 'administrations/sessions#new' + delete 'administrations/sign_out' => 'administrations/sessions#destroy' authenticate :administration do resources :administrations, only: [:index, :create] namespace :administrations do From 5c9d82d46f7697fe0d959d137a1af5a686f78a09 Mon Sep 17 00:00:00 2001 From: Mathieu Magnin Date: Wed, 20 Dec 2017 16:59:48 +0100 Subject: [PATCH 4/6] [Fix #1096] task to delete old accounts --- lib/tasks/2017_12_20_delete_old_administration.rake | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 lib/tasks/2017_12_20_delete_old_administration.rake diff --git a/lib/tasks/2017_12_20_delete_old_administration.rake b/lib/tasks/2017_12_20_delete_old_administration.rake new file mode 100644 index 000000000..2f72d4165 --- /dev/null +++ b/lib/tasks/2017_12_20_delete_old_administration.rake @@ -0,0 +1,8 @@ +namespace :'2017_12_20_delete_old_administration' do + task set: :environment do + Administration.all.each do |a| + puts "Deleting #{a.email}" + a.destroy + end + end +end From 39dc5718c263df0bd0ead820d7c581030fbee27a Mon Sep 17 00:00:00 2001 From: Mathieu Magnin Date: Wed, 20 Dec 2017 17:00:17 +0100 Subject: [PATCH 5/6] [Fix #1096] task to create new Administrations --- lib/tasks/admin.rake | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 lib/tasks/admin.rake diff --git a/lib/tasks/admin.rake b/lib/tasks/admin.rake new file mode 100644 index 000000000..93c89183e --- /dev/null +++ b/lib/tasks/admin.rake @@ -0,0 +1,12 @@ +namespace :admin do + task :create_admin, [:email] => :environment do |t, args| + email = args[:email] + puts "Creating Administration for #{email}" + a = Administration.new(email: email, password: Devise.friendly_token[0,20]) + if a.save + puts "#{a.email} created" + else + puts "An error occured : #{a.errors.full_messages}" + end + end +end From fab00b16749f0a314cd2cd6bb2c85761164ff345 Mon Sep 17 00:00:00 2001 From: Mathieu Magnin Date: Thu, 21 Dec 2017 15:04:03 +0100 Subject: [PATCH 6/6] [Fix #1096] Add administration email in new administrateur email --- app/controllers/administrations_controller.rb | 2 +- app/mailers/new_admin_mailer.rb | 3 ++- app/views/new_admin_mailer/new_admin_email.text.erb | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/controllers/administrations_controller.rb b/app/controllers/administrations_controller.rb index 2a8e22c16..c907a3b7a 100644 --- a/app/controllers/administrations_controller.rb +++ b/app/controllers/administrations_controller.rb @@ -18,7 +18,7 @@ class AdministrationsController < ApplicationController if admin.save flash.notice = "Administrateur créé" - NewAdminMailer.new_admin_email(admin).deliver_now! + NewAdminMailer.new_admin_email(admin, current_administration).deliver_now! else flash.alert = admin.errors.full_messages end diff --git a/app/mailers/new_admin_mailer.rb b/app/mailers/new_admin_mailer.rb index 71ea69b4f..96d0e76d4 100644 --- a/app/mailers/new_admin_mailer.rb +++ b/app/mailers/new_admin_mailer.rb @@ -1,6 +1,7 @@ class NewAdminMailer < ApplicationMailer - def new_admin_email admin + def new_admin_email admin, administration @admin = admin + @administration = administration mail(to: 'tech@tps.apientreprise.fr', subject: "Création d'un compte Admin TPS") diff --git a/app/views/new_admin_mailer/new_admin_email.text.erb b/app/views/new_admin_mailer/new_admin_email.text.erb index e0946ef9a..17e1d99c5 100644 --- a/app/views/new_admin_mailer/new_admin_email.text.erb +++ b/app/views/new_admin_mailer/new_admin_email.text.erb @@ -4,6 +4,8 @@ Plateforme : <%= TPS::Application::URL %> Login : <%= @admin.email %> +Créateur : <%= @administration.email %> + Bonne journée, L'équipe Téléprocédures Simplifiées