aceptar colaboraciones publicas

This commit is contained in:
f 2019-07-08 17:58:14 -03:00
parent a9990397ba
commit 067a6144e4
No known key found for this signature in database
GPG key ID: 2AE5A13E321F953D
11 changed files with 151 additions and 24 deletions

View file

@ -20,6 +20,7 @@ Metrics/AbcSize:
- 'app/controllers/invitadxs_controller.rb'
- 'app/controllers/i18n_controller.rb'
- 'app/controllers/usuaries_controller.rb'
- 'app/controllers/collaborations_controller.rb'
Metrics/MethodLength:
Exclude:
@ -30,6 +31,8 @@ Metrics/MethodLength:
- 'app/controllers/posts_controller.rb'
- 'app/controllers/invitadxs_controller.rb'
- 'app/controllers/i18n_controller.rb'
- 'app/controllers/collaborations_controller.rb'
Metrics/BlockLength:
Exclude:

View file

@ -0,0 +1,71 @@
# frozen_string_literal: true
# Controlador para gestionar colaboraciones abiertas
#
# No necesitamos autenticación aun
class CollaborationsController < ApplicationController
include Pundit
def collaborate
@site = Site.find_by_name(params[:site_id])
authorize Collaboration.new(@site)
@has_cover = true
@invitade = current_usuarie || @site.usuaries.build
end
# Aceptar una colaboración tiene varios pasos
#
# * Si le usuarie no existe, hay que crearle
#
# * Si le usuarie existe, hay que darle un rol si no lo tiene
#
# * Si le usuarie existe y no está logueade, pedirle la contraseña
def accept_collaboration
@site = Site.find_by_name(params[:site_id])
authorize Collaboration.new(@site)
@invitade = current_usuarie
@invitade ||= logged_out_invitade
# Salir si no se pudo validar le invitade
return if @invitade == false
Usuarie.transaction do
# Si la cuenta no existe, crearla
@invitade ||= Usuarie.create(invitade_params)
# Y asignar un rol si no existe
unless @invitade.rol_for_site(@site)
@site.roles << Rol.create(site: @site, usuarie: @invitade,
temporal: false, rol: 'invitade')
end
sign_in :usuarie, @invitade unless current_usuarie
redirect_to site_path(@site)
end
end
private
def invitade_params
params.require(:usuarie).permit(:email, :password)
end
def logged_out_invitade
invitade = Usuarie.find_by_email(invitade_params[:email])
return unless invitade
# Si la contraseña no es válida, volver atrás
if invitade.can_sign_in? invitade_params[:password]
invitade
else
invitade.increment_and_lock!
flash[:warning] = I18n.t('collaborations.password.incorrect')
redirect_to site_collaborate_path(@site)
false
end
end
end

View file

@ -0,0 +1,4 @@
# frozen_string_literal: true
# Una clase que contiene el sitio con el que se va a colaborar
Collaboration = Struct.new(:site)

View file

@ -14,4 +14,20 @@ class Usuarie < ApplicationRecord
def rol_for_site(site)
site.roles.merge(roles).first
end
# XXX: Ver increment_and_lock
def can_sign_in?(password)
active_for_authentication? && valid_password?(password)
end
# XXX: Estamos duplicando la forma en que Devise bloquea acceso
# por intentos fallidos porque no tenemos forma de correr
# validate() desde la estrategia DatabaseAuthenticatable sin
# generar una redirección.
#
# lib/devise/models/lockable.rb
def increment_and_lock!
increment_failed_attempts
lock_access! if attempts_exceeded? && !access_locked?
end
end

View file

@ -0,0 +1,12 @@
# frozen_string_literal: true
# Política de aceptación de colaboradorxs
CollaborationPolicy = Struct.new(:usuarie, :collaboration) do
def collaborate?
collaboration.site.invitadxs?
end
def accept_collaboration?
collaboration.site.invitadxs?
end
end

View file

@ -0,0 +1,24 @@
.row.align-items-center.justify-content-center.full-height
.col-md-10.align-self-center
= raw CommonMarker.render_doc(@site.config.dig('welcome', 'message') || t('.welcome')).to_html
.col-md-6.align-self-center
-# Copiado y pegado de app/views/devise/registrations/new.haml
- resource = resource_name = @invitade
= form_for(resource, as: resource_name, url: site_collaborate_path(@site), method: :post) do |f|
- unless current_usuarie
= render 'layouts/flash'
.form-group
= f.label :email
= f.email_field :email, autofocus: true, autocomplete: 'email',
class: 'form-control'
.form-group
= f.label :password
- if @minimum_password_length
%em= t('devise.shared.minimum_password_length', count: @minimum_password_length)
= f.password_field :password, autocomplete: 'new-password',
class: 'form-control'
.form-group
- button = @site.config.dig('welcome', 'button')
= f.submit t('.submit'), class: 'btn btn-lg btn-primary btn-block', style: (button) ? "background-color: #{button};" : ''

View file

@ -197,7 +197,7 @@ Devise.setup do |config|
# website without confirming their account.
# Default is 0.days, meaning the user cannot access the website
# without confirming their account.
config.allow_unconfirmed_access_for = 2.days
# config.allow_unconfirmed_access_for = 2.days
# A period that the user is allowed to confirm their account before
# their token becomes invalid. For example, if set to 3.days, the user

View file

@ -45,7 +45,7 @@ es:
not_found_in_database: "%{authentication_keys} o contraseña inválidos."
timeout: Tu sesión expiró. Por favor, inicia sesión nuevamente para continuar.
unauthenticated: Tienes que iniciar sesión o registrarte para poder continuar.
unconfirmed: Tienes que confirmar tu cuenta para poder continuar.
unconfirmed: Te enviamos un correo electrónico para confirmar tu cuenta, por favor acéptalo para poder continuar.
mailer:
confirmation_instructions:
action: Confirmar mi cuenta

View file

@ -20,11 +20,11 @@ en:
layouts:
breadcrumb:
help: Help
invitadx_mailer:
confirmation_required:
subject: "Confirm your e-mail address"
hi: "Hi!"
body: "Please open this link to confirm your e-mail address."
collaborations:
collaborate:
submit: Register
password:
incorrect: 'Wrong password, please try again.'
invitadxs:
index:
title: 'Guests'

View file

@ -1,5 +1,12 @@
es:
activerecord:
models:
usuarie: Usuarie
attributes:
usuarie:
email: 'Correo electrónico'
password: 'Contraseña'
password_confirmation: 'Confirmación de contraseña'
errors:
models:
invitadx:
@ -20,24 +27,11 @@ es:
layouts:
breadcrumb:
help: Ayuda
invitadx_mailer:
confirmation_required:
subject: "Confirma tu dirección de correo"
hi: "¡Hola!"
body: "Por favor abre esta dirección para confirmar tu cuenta de correo."
invitadxs:
index:
title: Invitadxs
new:
email: Correo electrónico
password: Contraseña
password_confirmation: Repite la contraseña
collaborations:
collaborate:
submit: Registrarme
acepta_politicas_de_privacidad: 'Acepto las <a href="%{privacy_policy}" target="_blank">Políticas de privacidad</a>.'
confirmation:
confirmed: 'Tu cuenta está confirmada, ahora puedes ingresar'
show:
confirmation_sent: "Te hemos enviado un correo de confirmación a tu casilla, por favor confirma tu cuenta antes de continuar."
password:
incorrect: 'Contraseña incorrecta, intenta nuevamente.'
info:
posts:
reorder: "¡Los artículos fueron reordenados!"

View file

@ -26,6 +26,9 @@ Rails.application.routes.draw do
patch 'promote', to: 'usuaries#promote'
end
get 'collaborate', to: 'collaborations#collaborate'
post 'collaborate', to: 'collaborations#accept_collaboration'
# Gestionar artículos
resources :posts