Merge pull request #1269 from betagouv/administrate-them-all

Administrate them all
This commit is contained in:
gregoirenovel 2018-01-18 10:27:39 +01:00 committed by GitHub
commit 13b5caf61d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 105 additions and 256 deletions

View file

@ -3,7 +3,7 @@ class Administrations::OmniauthCallbacksController < Devise::OmniauthCallbacksCo
administration = Administration.from_omniauth(request.env["omniauth.auth"]) administration = Administration.from_omniauth(request.env["omniauth.auth"])
if administration.present? if administration.present?
sign_in administration sign_in administration
redirect_to administrations_path redirect_to manager_administrateurs_path
else else
flash[:alert] = "Compte GitHub non autorisé" flash[:alert] = "Compte GitHub non autorisé"
redirect_to root_path redirect_to root_path

View file

@ -1,39 +0,0 @@
class AdministrationsController < ApplicationController
include SmartListing::Helper::ControllerExtensions
helper SmartListing::Helper
before_action :authenticate_administration!
def index
@admin = Administrateur.new
@admins = smart_listing_create :admins,
Administrateur.all.order(:email),
partial: "administrations/list",
array: true
end
def create
administrateur = current_administration.invite_admin(create_administrateur_params[:email])
if administrateur.errors.empty?
flash.notice = "Administrateur créé"
else
flash.alert = administrateur.errors.full_messages
end
redirect_to administrations_path
end
def update
Administrateur.find_inactive_by_id(params[:id]).invite!
redirect_to administrations_path
end
private
def create_administrateur_params
params.require(:administrateur).permit(:email)
end
end

View file

@ -1,21 +1,28 @@
module Manager module Manager
class AdministrateursController < Manager::ApplicationController class AdministrateursController < Manager::ApplicationController
# To customize the behavior of this controller, def create
# simply overwrite any of the RESTful actions. For example: administrateur = current_administration.invite_admin(create_administrateur_params[:email])
#
# def index
# super
# @resources = Administrateur.
# page(params[:page]).
# per(10)
# end
# Define a custom finder by overriding the `find_resource` method: if administrateur.errors.empty?
# def find_resource(param) flash.notice = "Administrateur créé"
# Administrateur.find_by!(slug: param) redirect_to manager_administrateurs_path
# end else
render :new, locals: {
page: Administrate::Page::Form.new(dashboard, administrateur),
}
end
end
# See https://administrate-prototype.herokuapp.com/customizing_controller_actions def reinvite
# for more information Administrateur.find_inactive_by_id(params[:id]).invite!
flash.notice = "Invitation renvoyée"
redirect_to manager_administrateur_path(params[:id])
end
private
def create_administrateur_params
params.require(:administrateur).permit(:email)
end
end end
end end

View file

@ -1,23 +1,21 @@
# All Administrate controllers inherit from this `Admin::ApplicationController`,
# making it the ideal place to put authentication logic or other
# before_actions.
#
# If you want to add pagination or other controller-level concerns,
# you're free to overwrite the RESTful controller actions.
module Manager module Manager
class ApplicationController < Administrate::ApplicationController class ApplicationController < Administrate::ApplicationController
before_action :authenticate_administration! before_action :authenticate_administration!
before_action :default_params before_action :default_params
# Override this value to specify the number of elements to display at a time
# on index pages. Defaults to 20.
# def records_per_page
# params[:per_page] || 20
# end
def default_params def default_params
params[:order] ||= "created_at" params[:order] ||= "created_at"
params[:direction] ||= "desc" params[:direction] ||= "desc"
end end
protected
def authenticate_administration!
if administration_signed_in?
super
else
redirect_to manager_sign_in_path
end
end
end end
end end

View file

@ -9,7 +9,7 @@ class RootController < ApplicationController
elsif user_signed_in? elsif user_signed_in?
return redirect_to users_dossiers_path return redirect_to users_dossiers_path
elsif administration_signed_in? elsif administration_signed_in?
return redirect_to administrations_path return redirect_to manager_root_path
end end
render 'landing' render 'landing'

View file

@ -12,7 +12,9 @@ class AdministrateurDashboard < Administrate::BaseDashboard
email: Field::String, email: Field::String,
created_at: Field::DateTime, created_at: Field::DateTime,
updated_at: Field::DateTime, updated_at: Field::DateTime,
procedures: Field::HasMany, procedures: Field::HasMany.with_options(limit: 20),
registration_state: Field::String.with_options(searchable: false),
current_sign_in_at: Field::DateTime,
}.freeze }.freeze
# COLLECTION_ATTRIBUTES # COLLECTION_ATTRIBUTES
@ -24,6 +26,7 @@ class AdministrateurDashboard < Administrate::BaseDashboard
:email, :email,
:created_at, :created_at,
:procedures, :procedures,
:registration_state,
].freeze ].freeze
# SHOW_PAGE_ATTRIBUTES # SHOW_PAGE_ATTRIBUTES
@ -33,13 +36,17 @@ class AdministrateurDashboard < Administrate::BaseDashboard
:email, :email,
:created_at, :created_at,
:updated_at, :updated_at,
:registration_state,
:current_sign_in_at,
:procedures, :procedures,
].freeze ].freeze
# FORM_ATTRIBUTES # FORM_ATTRIBUTES
# an array of attributes that will be displayed # an array of attributes that will be displayed
# on the model's form (`new` and `edit`) pages. # on the model's form (`new` and `edit`) pages.
FORM_ATTRIBUTES = [].freeze FORM_ATTRIBUTES = [
:email
].freeze
# Overwrite this method to customize how procedures are displayed # Overwrite this method to customize how procedures are displayed
# across all pages of the admin dashboard. # across all pages of the admin dashboard.

View file

@ -1,37 +0,0 @@
.card
- if smart_listing.present?
%table.table
%thead
%th.col-xs-4= smart_listing.sortable 'Email', :email
%th.col-xs-4= smart_listing.sortable 'Date de dernière connexion', :last_sign_in_at
%th.col-xs-2 État
%th.col-xs-2 Procédure active
%th.col-xs-2 Dossier en cours
- @admins.each do |admin|
%tr
%td
= admin.email
%td
- if admin.last_sign_in_at.present?
= time_ago_in_words(l(admin.last_sign_in_at, format: "%d/%m/%Y %H:%M UTC +02:00"))
(
= admin.last_sign_in_at.localtime.strftime('%d/%m/%Y')
)
%td
- if admin.invitation_expired?
= link_to admin.registration_state, administration_path(admin), remote: true, method: :patch
- else
= admin.registration_state
%td
= admin.procedures.publiees.count
%td
- total_dossier = 0
- admin.procedures.each do |procedure| total_dossier += procedure.dossiers.state_not_brouillon.count end
= total_dossier
= smart_listing.paginate
= smart_listing.pagination_per_page_links
- else
%h4.center
Aucun administrateur créé

View file

@ -1,15 +0,0 @@
.container
.mt-1
= form_for @admin, url: { controller: 'administrations', action: :create } do |f|
.form-group.form-inline.text-center
= f.text_field :email, placeholder: :email, class: 'form-control'
= f.submit 'Créer un administrateur', class: 'btn btn-success', id: 'submit_new_administrateur'
= smart_listing_render :admins
%br
%br
.text-center
= link_to 'Deconnexion', administrations_sign_out_path, method: :delete

View file

@ -1 +0,0 @@
<%= smart_listing_update :admins %>

View file

@ -45,7 +45,7 @@
= current_email = current_email
- if administration_signed_in? - if administration_signed_in?
%li %li
= link_to administrations_path, class: "menu-item menu-link" do = link_to manager_root_path, class: "menu-item menu-link" do
= image_tag "icons/super-admin.svg" = image_tag "icons/super-admin.svg"
Passer en super-admin Passer en super-admin
- if SwitchDeviseProfileService.new(warden).multiple_devise_profile_connect? - if SwitchDeviseProfileService.new(warden).multiple_devise_profile_connect?

View file

@ -0,0 +1,16 @@
- content_for(:title) do
= display_resource_name(page.resource_name)
- content_for(:search) do
- if show_search_bar
= render "search", search_term: search_term
%header.header
%h1.header__heading#page-title
= content_for(:title)
.header__actions
= link_to 'nouveau', new_manager_administrateur_path, class: 'button'
= render "collection", collection_presenter: page, resources: resources
= paginate resources

View file

@ -0,0 +1,15 @@
- content_for(:title) { page.page_title }
%header.header
%h1.header__heading= content_for(:title)
.header__actions
- if page.resource.invitation_expired?
= link_to "renvoyer l'invitation", reinvite_manager_administrateur_path(page.resource), method: :post, class: "button"
%dl
- page.attributes.each do |attribute|
%dt.attribute-label
= t("helpers.label.#{resource_name}.#{attribute.name}", default: attribute.name.titleize)
%dd.attribute-data{ class: "attribute-data--#{attribute.html_class}" }
= render_field attribute

View file

@ -1,21 +1,3 @@
-# # Collection
-#
-# This partial is used on the `index` and `show` pages
-# to display a collection of resources in an HTML table.
-#
-# ## Local variables:
-#
-# - `collection_presenter`:
-# An instance of [Administrate::Page::Collection][1].
-# The table presenter uses `ResourceDashboard::COLLECTION_ATTRIBUTES` to determine
-# the columns displayed in the table
-# - `resources`:
-# An ActiveModel::Relation collection of resources to be displayed in the table.
-# By default, the number of resources is limited by pagination
-# or by a hard limit to prevent excessive page load times
-#
-# [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Collection
%table.collection-data{ "aria-labelledby": "page-title" } %table.collection-data{ "aria-labelledby": "page-title" }
%thead %thead
%tr %tr

View file

@ -1,14 +1,3 @@
-# # Flash Partial
-#
-# This partial renders flash messages on every page.
-#
-# ## Relevant Helpers:
-#
-# - `flash`:
-# Returns a hash,
-# where the keys are the type of flash (alert, error, notice, etc)
-# and the values are the message to be displayed.
- if flash.any? - if flash.any?
.flashes .flashes
- flash.each do |key, value| - flash.each do |key, value|

View file

@ -1,10 +1,3 @@
-# # Javascript Partial
-#
-# This partial imports the necessary javascript on each page.
-# By default, it includes the application JS,
-# but each page can define additional JS sources
-# by providing a `content_for(:javascript)` block.
- Administrate::Engine.javascripts.each do |js_path| - Administrate::Engine.javascripts.each do |js_path|
= javascript_include_tag js_path = javascript_include_tag js_path

View file

@ -1,13 +1,6 @@
-# # Sidebar
-#
-# This partial is used to display the sidebar in Administrate.
-# By default, the sidebar contains navigation links
-# for all resources in the admin dashboard,
-# as defined by the routes in the `admin/` namespace
%ul.sidebar__list %ul.sidebar__list
%li %li
= link_to "Se déconnecter", administrations_sign_out_path, method: :delete, class: "sidebar__link" = link_to "Se déconnecter", manager_sign_out_path, method: :delete, class: "sidebar__link"
%hr{ style: "margin-bottom: 0;" } %hr{ style: "margin-bottom: 0;" }
@ -15,3 +8,9 @@
- Administrate::Namespace.new(namespace).resources.each do |resource| - Administrate::Namespace.new(namespace).resources.each do |resource|
%li %li
= link_to(display_resource_name(resource), [namespace, resource], class: "sidebar__link sidebar__link--#{nav_link_state(resource)}") = link_to(display_resource_name(resource), [namespace, resource], class: "sidebar__link sidebar__link--#{nav_link_state(resource)}")
%hr{ style: "margin-bottom: 0;" }
%ul.sidebar__list
%li
= link_to "Delayed Job", manager_delayed_job_path, class: "sidebar__link"

View file

@ -1,26 +1,3 @@
-# # Index
-#
-# This view is the template for the index page.
-# It is responsible for rendering the search bar, header and pagination.
-# It renders the `_table` partial to display details about the resources.
-#
-# ## Local variables:
-#
-# - `page`:
-# An instance of [Administrate::Page::Collection][1].
-# Contains helper methods to help display a table,
-# and knows which attributes should be displayed in the resource's table.
-# - `resources`:
-# An instance of `ActiveRecord::Relation` containing the resources
-# that match the user's search criteria.
-# By default, these resources are passed to the table partial to be displayed.
-# - `search_term`:
-# A string containing the term the user has searched for, if any.
-# - `show_search_bar`:
-# A boolean that determines if the search bar should be shown.
-#
-# [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Collection
- content_for(:title) do - content_for(:title) do
= display_resource_name(page.resource_name) = display_resource_name(page.resource_name)

View file

@ -1,19 +1,3 @@
-# # Show
-#
-# This view is the template for the show page.
-# It renders the attributes of a resource,
-# as well as a link to its edit page.
-#
-# ## Local variables:
-#
-# - `page`:
-# An instance of [Administrate::Page::Show][1].
-# Contains methods for accessing the resource to be displayed on the page,
-# as well as helpers for describing how each attribute of the resource
-# should be displayed.
-#
-# [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Show
- content_for(:title) { page.page_title } - content_for(:title) { page.page_title }
%header.header %header.header

View file

@ -1,19 +1,3 @@
-# # Show
-#
-# This view is the template for the show page.
-# It renders the attributes of a resource,
-# as well as a link to its edit page.
-#
-# ## Local variables:
-#
-# - `page`:
-# An instance of [Administrate::Page::Show][1].
-# Contains methods for accessing the resource to be displayed on the page,
-# as well as helpers for describing how each attribute of the resource
-# should be displayed.
-#
-# [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Show
- content_for(:title) { page.page_title } - content_for(:title) { page.page_title }
- procedure = page.resource - procedure = page.resource

View file

@ -0,0 +1,8 @@
fr:
activerecord:
errors:
models:
administrateur:
attributes:
email:
blank: 'doit être rempli'

View file

@ -1,12 +1,20 @@
Rails.application.routes.draw do Rails.application.routes.draw do
get 'manager/sign_in' => 'administrations/sessions#new'
delete 'manager/sign_out' => 'administrations/sessions#destroy'
namespace :manager do namespace :manager do
resources :procedures, only: [:index, :show] do resources :procedures, only: [:index, :show] do
post 'whitelist', on: :member post 'whitelist', on: :member
end end
resources :administrateurs, only: [:index, :show] resources :administrateurs, only: [:index, :show, :new, :create] do
post 'reinvite', on: :member
end
root to: "procedures#index" authenticate :administration do
match "/delayed_job" => DelayedJobWeb, :anchor => false, :via => [:get, :post]
end
root to: "administrateurs#index"
end end
get "/ping" => "ping#index", :constraints => {:ip => /127.0.0.1/} get "/ping" => "ping#index", :constraints => {:ip => /127.0.0.1/}
@ -52,14 +60,6 @@ Rails.application.routes.draw do
get 'users' => 'users#index' get 'users' => 'users#index'
get 'admin' => 'admin#index' get 'admin' => 'admin#index'
get 'administrations/sign_in' => 'administrations/sessions#new'
delete 'administrations/sign_out' => 'administrations/sessions#destroy'
authenticate :administration do
resources :administrations, only: [:index, :create, :update] do
match "/delayed_job" => DelayedJobWeb, :anchor => false, :via => [:get, :post]
end
end
resources :stats, only: [:index] resources :stats, only: [:index]
namespace :france_connect do namespace :france_connect do

View file

@ -18,7 +18,7 @@ describe Administrations::OmniauthCallbacksController, type: :controller do
let(:administration) { create(:administration, email: email) } let(:administration) { create(:administration, email: email) }
before { administration } before { administration }
it { is_expected.to redirect_to(administrations_path) } it { is_expected.to redirect_to(manager_administrateurs_path) }
it do it do
expect(controller).to receive(:sign_in).with(administration) expect(controller).to receive(:sign_in).with(administration)
subject subject

View file

@ -1,23 +1,5 @@
require 'spec_helper' describe Manager::AdministrateursController, type: :controller do
let(:administration){ create(:administration) }
describe AdministrationsController, type: :controller do
let(:administration) { create :administration }
describe 'GET #index' do
subject { get :index }
context 'when administration user is not connect' do
it { expect(subject.status).to eq 302 }
end
context 'when administration user is connect' do
before do
sign_in administration
end
it { expect(subject.status).to eq 200 }
end
end
describe 'POST #create' do describe 'POST #create' do
let(:email) { 'plop@plop.com' } let(:email) { 'plop@plop.com' }
@ -27,7 +9,7 @@ describe AdministrationsController, type: :controller do
sign_in administration sign_in administration
end end
subject { post :create, administrateur: {email: email } } subject { post :create, administrateur: { email: email } }
context 'when email and password are correct' do context 'when email and password are correct' do
it 'add new administrateur in database' do it 'add new administrateur in database' do

View file

@ -37,7 +37,7 @@ describe RootController, type: :controller do
sign_in create(:administration) sign_in create(:administration)
end end
it { expect(subject).to redirect_to(administrations_path) } it { expect(subject).to redirect_to(manager_root_path) }
end end
context 'when nobody is connected' do context 'when nobody is connected' do