pedir consentimiento para invitaciones
This commit is contained in:
parent
1bf3fc0128
commit
a9990397ba
12 changed files with 139 additions and 141 deletions
|
@ -1,65 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Controlador de Invitadxs
|
|
||||||
#
|
|
||||||
# TODO: reemplazar
|
|
||||||
class InvitadxsController < ApplicationController
|
|
||||||
include Pundit
|
|
||||||
|
|
||||||
def index
|
|
||||||
authenticate_usuarie!
|
|
||||||
|
|
||||||
@site = find_site
|
|
||||||
@invitadxs = @site.invitadxs
|
|
||||||
end
|
|
||||||
|
|
||||||
def new
|
|
||||||
@site = Site.find(params[:site_id])
|
|
||||||
@has_cover = true
|
|
||||||
@invitadx = Invitadx.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@site = Site.find(params[:invitadx][:site])
|
|
||||||
@invitadx = Invitadx.new(invitadx_params)
|
|
||||||
@invitadx.confirmation_token = SecureRandom.hex(16)
|
|
||||||
@invitadx.sites << @site
|
|
||||||
|
|
||||||
if @invitadx.save
|
|
||||||
InvitadxMailer.with(site: @site, invitadx: @invitadx)
|
|
||||||
.confirmation_required.deliver
|
|
||||||
redirect_to site_invitadx_path(@site, @invitadx)
|
|
||||||
else
|
|
||||||
render 'new'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def show
|
|
||||||
@site = Site.find(params[:site_id])
|
|
||||||
@has_cover = true
|
|
||||||
@invitadx = Invitadx.find(params[:id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def confirmation
|
|
||||||
@invitadx = Invitadx.find(params[:invitadx_id])
|
|
||||||
@site = @invitadx.sites.find do |site|
|
|
||||||
site.id == params[:site_id]
|
|
||||||
end
|
|
||||||
|
|
||||||
if (@invitadx.confirmation_token = params[:confirmation_token])
|
|
||||||
@invitadx.update_attribute :confirmed, true
|
|
||||||
flash[:info] = t('.confirmed')
|
|
||||||
redirect_to site_invitadxs_login_new_path(@site)
|
|
||||||
else
|
|
||||||
redirect_to root_path
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def invitadx_params
|
|
||||||
params.require(:invitadx).permit(:email, :password,
|
|
||||||
:password_confirmation,
|
|
||||||
:acepta_politicas_de_privacidad)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -67,10 +67,13 @@ class UsuariesController < ApplicationController
|
||||||
authorize SiteUsuarie.new(@site, current_usuarie)
|
authorize SiteUsuarie.new(@site, current_usuarie)
|
||||||
|
|
||||||
# Enviar la invitación si es necesario y agregar al sitio
|
# Enviar la invitación si es necesario y agregar al sitio
|
||||||
#
|
|
||||||
# TODO: Pedir consentimiento para agregar a un sitio!
|
|
||||||
invitaciones.each do |invitacion|
|
invitaciones.each do |invitacion|
|
||||||
# Si la cuenta no existe, envía una invitación por correo
|
# Si la cuenta no existe, envía una invitación por correo, sino,
|
||||||
|
# no se envía nada
|
||||||
|
#
|
||||||
|
# TODO: Enviar invitación igual! Podemos no usar el Mailer de
|
||||||
|
# DeviseInvitations y usar uno propio que contenga texto y se
|
||||||
|
# envíe de todas formas.
|
||||||
usuarie = Usuarie.invite! email: invitacion.address
|
usuarie = Usuarie.invite! email: invitacion.address
|
||||||
|
|
||||||
# No invitar al sitio si ya estaba en la lista!
|
# No invitar al sitio si ya estaba en la lista!
|
||||||
|
@ -83,6 +86,26 @@ class UsuariesController < ApplicationController
|
||||||
redirect_to site_usuaries_path(@site)
|
redirect_to site_usuaries_path(@site)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Aceptar la invitación
|
||||||
|
def accept_invitation
|
||||||
|
@site = find_site
|
||||||
|
authorize SiteUsuarie.new(@site, current_usuarie)
|
||||||
|
|
||||||
|
current_usuarie.rol_for_site(@site).update_attribute :temporal, false
|
||||||
|
|
||||||
|
redirect_to sites_path
|
||||||
|
end
|
||||||
|
|
||||||
|
# Declinar la invitación
|
||||||
|
def reject_invitation
|
||||||
|
@site = find_site
|
||||||
|
authorize SiteUsuarie.new(@site, current_usuarie)
|
||||||
|
|
||||||
|
current_usuarie.rol_for_site(@site).destroy
|
||||||
|
|
||||||
|
redirect_to sites_path
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Traer todas las invitaciones que al menos tengan usuarie y dominio
|
# Traer todas las invitaciones que al menos tengan usuarie y dominio
|
||||||
|
|
|
@ -11,4 +11,12 @@ class Rol < ApplicationRecord
|
||||||
belongs_to :site
|
belongs_to :site
|
||||||
|
|
||||||
validates_inclusion_of :rol, in: ROLES
|
validates_inclusion_of :rol, in: ROLES
|
||||||
|
|
||||||
|
def invitade?
|
||||||
|
rol == 'invitade'
|
||||||
|
end
|
||||||
|
|
||||||
|
def usuarie?
|
||||||
|
rol == 'usuarie'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,4 +10,8 @@ class Usuarie < ApplicationRecord
|
||||||
|
|
||||||
has_many :roles
|
has_many :roles
|
||||||
has_many :sites, through: :roles
|
has_many :sites, through: :roles
|
||||||
|
|
||||||
|
def rol_for_site(site)
|
||||||
|
site.roles.merge(roles).first
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -35,9 +35,22 @@ class SiteUsuariePolicy
|
||||||
usuarie?
|
usuarie?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def accept_invitation?
|
||||||
|
su = site_usuarie
|
||||||
|
(usuarie? || invitade?) && su.usuarie.rol_for_site(su.site).temporal
|
||||||
|
end
|
||||||
|
|
||||||
|
def reject_invitation?
|
||||||
|
accept_invitation?
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def usuarie?
|
def usuarie?
|
||||||
site_usuarie.site.usuarie? usuarie
|
site_usuarie.site.usuarie? usuarie
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def invitade?
|
||||||
|
site_usuarie.site.invitade? usuarie
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
.row
|
|
||||||
.col
|
|
||||||
= render 'layouts/breadcrumb', crumbs: [ t('sites.index'), t('.title') ]
|
|
||||||
.row
|
|
||||||
.col
|
|
||||||
%h1= t('.title')
|
|
||||||
|
|
||||||
%table.table.table-striped.table-condensed
|
|
||||||
%tbody
|
|
||||||
- @invitadxs.each do |invitadx|
|
|
||||||
%tr
|
|
||||||
%td= invitadx.email
|
|
||||||
%td= invitadx.created_at
|
|
|
@ -1,2 +1,2 @@
|
||||||
= link_to text, link, class: "btn btn-#{type || secondary}",
|
= link_to text, link, class: "btn btn-#{type || secondary}",
|
||||||
data: { toggle: 'tooltip' }, title: tooltip
|
data: { toggle: 'tooltip' }, 'aria-role': 'button', title: tooltip
|
||||||
|
|
|
@ -21,6 +21,20 @@
|
||||||
= t('.invitade')
|
= t('.invitade')
|
||||||
%br
|
%br
|
||||||
.btn-group{role: 'group', 'aria-label': t('sites.actions')}
|
.btn-group{role: 'group', 'aria-label': t('sites.actions')}
|
||||||
|
- if current_usuarie.rol_for_site(site).temporal
|
||||||
|
= button_to t('sites.invitations.accept'),
|
||||||
|
site_usuaries_accept_invitation_path(site),
|
||||||
|
data: { toggle: 'tooltip' },
|
||||||
|
title: t('help.sites.invitations.accept'),
|
||||||
|
method: :patch,
|
||||||
|
class: 'btn btn-success'
|
||||||
|
= button_to t('sites.invitations.reject'),
|
||||||
|
site_usuaries_reject_invitation_path(site),
|
||||||
|
data: { toggle: 'tooltip' },
|
||||||
|
title: t('help.sites.invitations.reject'),
|
||||||
|
method: :patch,
|
||||||
|
class: 'btn btn-info'
|
||||||
|
- else
|
||||||
- if policy(site).show?
|
- if policy(site).show?
|
||||||
= render 'layouts/btn_with_tooltip',
|
= render 'layouts/btn_with_tooltip',
|
||||||
tooltip: t('help.sites.edit_posts'),
|
tooltip: t('help.sites.edit_posts'),
|
||||||
|
|
|
@ -90,6 +90,9 @@ en:
|
||||||
build_log: "This is the log for what happened during site
|
build_log: "This is the log for what happened during site
|
||||||
generation. If there was an issue, you'll see it here."
|
generation. If there was an issue, you'll see it here."
|
||||||
invitade: "Invited users can only add and modify entries but can't publish until reviewed by a user"
|
invitade: "Invited users can only add and modify entries but can't publish until reviewed by a user"
|
||||||
|
invitations:
|
||||||
|
accept: 'Someone invited you to collaborate on their site. If you accept the invitation, you can access the site.'
|
||||||
|
reject: 'If you decline, nothing happens.'
|
||||||
close: 'Close help'
|
close: 'Close help'
|
||||||
markdown:
|
markdown:
|
||||||
intro: 'The text is formatted using a syntax called Markdown, a
|
intro: 'The text is formatted using a syntax called Markdown, a
|
||||||
|
@ -146,6 +149,9 @@ en:
|
||||||
enqueue: 'Build'
|
enqueue: 'Build'
|
||||||
failed: 'Failed!'
|
failed: 'Failed!'
|
||||||
build_log: 'Read log'
|
build_log: 'Read log'
|
||||||
|
invitations:
|
||||||
|
accept: 'Accept invitation'
|
||||||
|
reject: 'No, thanks'
|
||||||
footer:
|
footer:
|
||||||
powered_by: 'is developed by'
|
powered_by: 'is developed by'
|
||||||
templates:
|
templates:
|
||||||
|
|
|
@ -100,6 +100,9 @@ es:
|
||||||
build_log: 'Este es el registro de lo que sucedió mientras se
|
build_log: 'Este es el registro de lo que sucedió mientras se
|
||||||
generaba el sitio. Si hubo algún problema, saldrá aquí.'
|
generaba el sitio. Si hubo algún problema, saldrá aquí.'
|
||||||
invitade: 'Les invitades a un sitio solo pueden crear y modificar entradas propias y no pueden publicar sin la revisión de une usuarie'
|
invitade: 'Les invitades a un sitio solo pueden crear y modificar entradas propias y no pueden publicar sin la revisión de une usuarie'
|
||||||
|
invitations:
|
||||||
|
accept: 'Alguien te invitó a colaborar en su sitio. Si aceptas la invitación, tendrás acceso a este sitio.'
|
||||||
|
reject: 'Si rechazas la invitación, no pasa nada.'
|
||||||
close: 'Cerrar ayuda'
|
close: 'Cerrar ayuda'
|
||||||
markdown:
|
markdown:
|
||||||
intro: 'El formato del texto se llama Markdown. Es un formato
|
intro: 'El formato del texto se llama Markdown. Es un formato
|
||||||
|
@ -155,6 +158,9 @@ es:
|
||||||
enqueue: 'Compilar'
|
enqueue: 'Compilar'
|
||||||
failed: '¡Falló!'
|
failed: '¡Falló!'
|
||||||
build_log: 'Ver registro'
|
build_log: 'Ver registro'
|
||||||
|
invitations:
|
||||||
|
accept: 'Aceptar la invitación'
|
||||||
|
reject: 'No, gracias'
|
||||||
footer:
|
footer:
|
||||||
powered_by: 'es desarrollada por'
|
powered_by: 'es desarrollada por'
|
||||||
i18n:
|
i18n:
|
||||||
|
|
|
@ -19,6 +19,8 @@ Rails.application.routes.draw do
|
||||||
# Gestionar usuaries
|
# Gestionar usuaries
|
||||||
get 'usuaries/invite', to: 'usuaries#invite'
|
get 'usuaries/invite', to: 'usuaries#invite'
|
||||||
post 'usuaries/invite', to: 'usuaries#send_invitations'
|
post 'usuaries/invite', to: 'usuaries#send_invitations'
|
||||||
|
patch 'usuaries/accept_invitation', to: 'usuaries#accept_invitation'
|
||||||
|
patch 'usuaries/reject_invitation', to: 'usuaries#reject_invitation'
|
||||||
resources :usuaries do
|
resources :usuaries do
|
||||||
patch 'demote', to: 'usuaries#demote'
|
patch 'demote', to: 'usuaries#demote'
|
||||||
patch 'promote', to: 'usuaries#promote'
|
patch 'promote', to: 'usuaries#promote'
|
||||||
|
|
|
@ -12,7 +12,7 @@ artículos y modificar los propios).
|
||||||
No nos gusta la idea de implementar todo un sistema de privilegios,
|
No nos gusta la idea de implementar todo un sistema de privilegios,
|
||||||
primero porque queremos que Sutty sea una plataforma democrática y
|
primero porque queremos que Sutty sea una plataforma democrática y
|
||||||
segundo porque en nuestra experiencia nadie los usa y prefieren usar una
|
segundo porque en nuestra experiencia nadie los usa y prefieren usar una
|
||||||
cuenta de administración.
|
cuenta de administración para todo.
|
||||||
|
|
||||||
La migración a Devise nos va a permitir tener recuperación de
|
La migración a Devise nos va a permitir tener recuperación de
|
||||||
contraseñas, registro independiente, correos de bienvenida y varias
|
contraseñas, registro independiente, correos de bienvenida y varias
|
||||||
|
@ -27,21 +27,17 @@ integrarla con otras plataformas comunitarias
|
||||||
Los Sitios tienen una contraparte física, de archivos, pero también se
|
Los Sitios tienen una contraparte física, de archivos, pero también se
|
||||||
crean en la base de datos para establecer relaciones con Usuaries.
|
crean en la base de datos para establecer relaciones con Usuaries.
|
||||||
|
|
||||||
Une Usuarie puede tener muchos Sitios y viceversa. En Rails esto se
|
Une Usuarie puede tener muchos Sitios y viceversa.
|
||||||
llama "tiene y pertenece a muchos" (HABTM en inglés).
|
|
||||||
|
|
||||||
Sin embargo también queremos saber qué rol tienen, con lo que
|
También queremos saber qué rol tienen, con lo que tenemos una tabla de
|
||||||
necesitamos dos tablas de HABTM, una de Invitades y otra de Usuaries.
|
roles que establece el rol que une usuarie tiene en un sitio. De lo
|
||||||
De lo contrario necesitamos establecer roles y ya entramos en las
|
contrario necesitamos establecer roles y ya entramos en las dificultades
|
||||||
dificultades que decíamos más arriba.
|
que decíamos más arriba.
|
||||||
|
|
||||||
No podemos saber desde cuándo se creo la relación, a menos que tengamos
|
|
||||||
una tabla de actividades por separado.
|
|
||||||
|
|
||||||
Podemos saber quién es invitade ingresando a un sitio y fijándonos si
|
Podemos saber quién es invitade ingresando a un sitio y fijándonos si
|
||||||
está en su lista de invitade. Lo mismo para usuaries.
|
está en su lista de invitade. Lo mismo para usuaries.
|
||||||
|
|
||||||
Les usuaries pueden bloquear invitades y a otres usuaries, y sumar
|
Les usuaries pueden bloquear invitades y a otres usuaries y sumar
|
||||||
usuaries e invitades a su sitio (via correo de invitación).
|
usuaries e invitades a su sitio (via correo de invitación).
|
||||||
|
|
||||||
## Invitaciones a sitios
|
## Invitaciones a sitios
|
||||||
|
@ -56,15 +52,19 @@ participación.
|
||||||
Si no tienen cuenta, tienen que registrarse completando los datos en el
|
Si no tienen cuenta, tienen que registrarse completando los datos en el
|
||||||
momento, sino se pueden loguear normalmente.
|
momento, sino se pueden loguear normalmente.
|
||||||
|
|
||||||
Si ya están logueades, se acepta la invitación inmediatamente.
|
Para poder hacer una invitación con consentimiento, se guarda el rol
|
||||||
|
como temporal. Cuando la usuaria acepta la invitación el rol se vuelve
|
||||||
|
definitivo.
|
||||||
|
|
||||||
Para poder hacer una invitación con consentimiento, se guarda la
|
### Aceptar invitación
|
||||||
relación en una tabla aparte. Cuando la usuaria acepta la invitación
|
|
||||||
esa relación se borra y se aplican los cambios.
|
|
||||||
|
|
||||||
En el futuro cambiaríamos el sistema de permisos separados que tenemos
|
Al ingresar, le usuarie ve su listado de sitios y en la lista ve a
|
||||||
ahora por una tabla de roles (por qué no la hicimos desde el principio!)
|
cuales está invitade. Usa el botón de aceptar invitación para poder
|
||||||
con un campo binario que indique si ya se aceptó la invitación o no.
|
acceder al sitio. Si rechaza la invitación, el rol se elimina de la
|
||||||
|
base de datos.
|
||||||
|
|
||||||
|
Eventualmente queremos pasar a un modelo de estados del rol donde
|
||||||
|
podamos saber si fue rechazado, aceptado, etc.
|
||||||
|
|
||||||
### Invitades desde la web
|
### Invitades desde la web
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue