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: {
# See https://administrate-prototype.herokuapp.com/customizing_controller_actions page: Administrate::Page::Form.new(dashboard, administrateur),
# for more information }
end
end
def reinvite
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' }

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