diff --git a/app/models/indexed_post.rb b/app/models/indexed_post.rb index 7f6865f6..184cd05f 100644 --- a/app/models/indexed_post.rb +++ b/app/models/indexed_post.rb @@ -36,6 +36,15 @@ class IndexedPost < ApplicationRecord belongs_to :site + # Encuentra el post original + # + # @return [nil,Post] + def post + return if post_id.blank? + + @post ||= site.posts(lang: locale).find(post_id, uuid: true) + end + # Convertir locale a direccionario de PG # # @param [String,Symbol] diff --git a/app/policies/indexed_post_policy.rb b/app/policies/indexed_post_policy.rb new file mode 100644 index 00000000..e0151c7a --- /dev/null +++ b/app/policies/indexed_post_policy.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +# Política de acceso a artículos +class IndexedPostPolicy + attr_reader :indexed_post, :usuarie, :site + + def initialize(usuarie, indexed_post) + @usuarie = usuarie + @indexed_post = indexed_post + @site = indexed_post.site + end + + def index? + true + end + + # Les invitades solo pueden ver sus propios posts + def show? + site.usuarie?(usuarie) || site.indexed_posts.by_usuarie(usuarie.id).find_by_post_id(indexed_post.post_id).present? + end + + def preview? + show? + end + + def new? + create? + end + + def create? + true + end + + def edit? + update? + end + + # Les invitades solo pueden modificar sus propios artículos + def update? + show? + end + + # Solo las usuarias pueden eliminar artículos. Les invitades pueden + # borrar sus propios artículos + def destroy? + update? + end + + # Las usuarias pueden ver todos los posts + # + # Les invitades solo pueden ver sus propios posts + class Scope + attr_reader :usuarie, :scope + + def initialize(usuarie, scope) + @usuarie = usuarie + @scope = scope + end + + def resolve + return scope if scope&.first&.site&.usuarie? usuarie + + scope.by_usuarie(usuarie.id) + end + end +end diff --git a/app/views/sites/_form.haml b/app/views/sites/_form.haml index 13a948a0..434e3495 100644 --- a/app/views/sites/_form.haml +++ b/app/views/sites/_form.haml @@ -46,36 +46,37 @@ .invalid-feedback= site.errors.messages[:description].join(', ') %hr/ - .form-group#design_id - %h2= t('.design.title') - %p.lead= t('.help.design') - - if invalid? site, :design_id - = render 'bootstrap/alert' do - = t('activerecord.errors.models.site.attributes.design_id.layout_incompatible.help', - layouts: site.incompatible_layouts.to_sentence) - .row.row-cols-1.row-cols-md-2.designs - -# Demasiado complejo para un f.collection_radio_buttons - - Design.all.order(priority: :desc).each do |design| - .design.col.d-flex.flex-column - .custom-control.custom-radio - = f.radio_button :design_id, design.id, - checked: design.id == site.design_id, - disabled: design.disabled, - required: true, class: 'custom-control-input' - = f.label "design_id_#{design.id}", design.name, - class: 'custom-control-label' - .flex-fill - = sanitize_markdown design.description, - tags: %w[p a strong em] + - unless site.persisted? + .form-group#design_id + %h2= t('.design.title') + %p.lead= t('.help.design') + - if invalid? site, :design_id + = render 'bootstrap/alert' do + = t('activerecord.errors.models.site.attributes.design_id.layout_incompatible.help', + layouts: site.incompatible_layouts.to_sentence) + .row.row-cols-1.row-cols-md-2.designs + -# Demasiado complejo para un f.collection_radio_buttons + - Design.all.order(priority: :desc).each do |design| + .design.col.d-flex.flex-column + .custom-control.custom-radio + = f.radio_button :design_id, design.id, + checked: design.id == site.design_id, + disabled: design.disabled, + required: true, class: 'custom-control-input' + = f.label "design_id_#{design.id}", design.name, + class: 'custom-control-label' + .flex-fill + = sanitize_markdown design.description, + tags: %w[p a strong em] - .btn-group{ role: 'group', 'aria-label': t('.design.actions') } - - if design.url - = link_to t('.design.url'), design.url, - target: '_blank', class: 'btn' - - if design.license - = link_to t('.design.license'), design.license, - target: '_blank', class: 'btn' - %hr/ + .btn-group{ role: 'group', 'aria-label': t('.design.actions') } + - if design.url + = link_to t('.design.url'), design.url, + target: '_blank', class: 'btn' + - if design.license + = link_to t('.design.license'), design.license, + target: '_blank', class: 'btn' + %hr/ .form-group.licenses#license_id %h2= t('.licencia.title') diff --git a/config/locales/en.yml b/config/locales/en.yml index 2055d5f3..8257fed6 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -414,7 +414,7 @@ en: name: "This will be the host name for your site, ie. **example**.sutty.nl. Choose an expression up to 63 characters. It can contain only lowercase letters, numbers and dashes, **and no spaces**. It can't start or end with a dash, or be entirely composed of numbers." title: 'The title can be anything you want.' description: 'You site description that appears in search engines. Between 10 and 160 characters.' - design: 'Select the design for your site. You can change it later. We add more designs from time to time!' + design: 'Select the design for your site. We add more designs from time to time!' licencia: 'Everything we publish has automatic copyright. This means nobody can use our works without explicit permission. By using licenses, we stablish conditions by which we want to share diff --git a/config/locales/es.yml b/config/locales/es.yml index 9f671b39..ec8e1afa 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -420,7 +420,7 @@ es: name: 'El nombre de tu sitio que formará parte de la dirección (**ejemplo**.sutty.nl). Solo puede contener hasta 63 letras minúsculas, números y guiones, pero **sin espacios**. No puede empezar ni terminar con guión, ni estar compuesto enteramente por números.' title: 'El título de tu sitio puede ser lo que quieras.' description: 'La descripción del sitio, que saldrá en buscadores. Entre 10 y 160 caracteres.' - design: 'Elegí el diseño que va a tener tu sitio aquí. Podés cambiarlo luego. De tanto en tanto vamos sumando diseños nuevos.' + design: 'Elegí el diseño que va a tener tu sitio aquí. De tanto en tanto vamos sumando diseños nuevos.' licencia: 'Todo lo que publicamos posee automáticamente derechos de autore. Esto significa que nadie puede hacer uso de nuestras obras sin permiso explícito. Con las licencias establecemos