mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-22 10:36:22 +00:00
version privadas del sitio #180
se puede compilar una versión privada del sitio solo accesible a través del panel, es decir con los mismos niveles de acceso. en combinación con el complemento de jekyll correspondiente, sería posible ver un sitio con otros datos que no se publican.
This commit is contained in:
parent
bcab506ff3
commit
f77a907753
11 changed files with 160 additions and 5 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -24,6 +24,7 @@
|
|||
|
||||
/_sites/*
|
||||
/_deploy/*
|
||||
/_private/*
|
||||
/data/*
|
||||
/_storage/*
|
||||
|
||||
|
|
|
@ -103,6 +103,7 @@ RUN ln -s data/_storage /srv/http/_storage
|
|||
RUN ln -s data/_sites /srv/http/_sites
|
||||
RUN ln -s data/_deploy /srv/http/_deploy
|
||||
RUN ln -s data/_public /srv/http/_public
|
||||
RUN ln -s data/_private /srv/http/_private
|
||||
|
||||
# Volver a root para cerrar la compilación
|
||||
USER root
|
||||
|
|
76
app/controllers/private_controller.rb
Normal file
76
app/controllers/private_controller.rb
Normal file
|
@ -0,0 +1,76 @@
|
|||
# Gestiona las versiones privadas de los sitios. Solo se puede acceder
|
||||
# con una cuenta
|
||||
class PrivateController < ApplicationController
|
||||
# XXX: Permite ejecutar JS
|
||||
skip_forgery_protection
|
||||
|
||||
include Pundit
|
||||
rescue_from Pundit::NilPolicyError, with: :page_not_found
|
||||
|
||||
# Enviar el archivo si existe, agregar una / al final siempre para no
|
||||
# romper las direcciones relativas.
|
||||
def show
|
||||
authorize site
|
||||
|
||||
# Detectar si necesitamos una / al final
|
||||
if needs_trailing_slash?
|
||||
redirect_to request.url + '/'
|
||||
return
|
||||
end
|
||||
|
||||
if deploy_private
|
||||
send_file path, disposition: 'inline'
|
||||
else
|
||||
head :not_found
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Detects if the URL should have a trailing slash
|
||||
def needs_trailing_slash?
|
||||
!trailing_slash? && params[:format].blank?
|
||||
end
|
||||
|
||||
def trailing_slash?
|
||||
request.env['REQUEST_URI'].ends_with?('/')
|
||||
end
|
||||
|
||||
def site
|
||||
@site ||= find_site
|
||||
end
|
||||
|
||||
def deploy_private
|
||||
@deploy_private ||= site.deploys.find_by(type: 'DeployPrivate')
|
||||
end
|
||||
|
||||
# Devuelve la ruta completa del archivo
|
||||
def path
|
||||
return @path if @path
|
||||
|
||||
@path = Pathname.new(File.join(deploy_private.destination, file)).realpath.to_s
|
||||
|
||||
raise Errno::ENOENT unless @path.starts_with? deploy_private.destination
|
||||
|
||||
@path
|
||||
rescue Errno::ENOENT
|
||||
File.join(deploy_private.destination, '404.html')
|
||||
end
|
||||
|
||||
# Devuelve la ruta del archivo, limpieza copiada desde Jekyll
|
||||
#
|
||||
# @see Jekyll::URL#sanitize_url
|
||||
def file
|
||||
return @file if @file
|
||||
|
||||
@file = params[:file] || '/'
|
||||
@file += '/' if trailing_slash?
|
||||
@file += if @file.ends_with? '/'
|
||||
'index.html'
|
||||
else
|
||||
'.' + params[:format].to_s
|
||||
end
|
||||
|
||||
@file = @file.gsub('..', '/').gsub('./', '').squeeze('/')
|
||||
end
|
||||
end
|
23
app/models/deploy_private.rb
Normal file
23
app/models/deploy_private.rb
Normal file
|
@ -0,0 +1,23 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Permite generar el sitio en una versión privada, mostrando información
|
||||
# que no se vería públicamente (borradores, campos privados, etc.)
|
||||
#
|
||||
# XXX: La plantilla tiene que soportar esto con el plugin
|
||||
# jekyll-private-data
|
||||
class DeployPrivate < DeployLocal
|
||||
# No es necesario volver a instalar dependencias
|
||||
def deploy
|
||||
jekyll_build
|
||||
end
|
||||
|
||||
# Hacer el deploy a un directorio privado
|
||||
def destination
|
||||
File.join(Rails.root, '_private', site.name)
|
||||
end
|
||||
|
||||
# No usar recursos en compresión y habilitar los datos privados
|
||||
def env
|
||||
@env ||= super.merge({ 'JEKYLL_ENV' => 'development', 'JEKYLL_PRIVATE' => 'true' })
|
||||
end
|
||||
end
|
|
@ -15,7 +15,7 @@ class Site < ApplicationRecord
|
|||
|
||||
# TODO: Hacer que los diferentes tipos de deploy se auto registren
|
||||
# @see app/services/site_service.rb
|
||||
DEPLOYS = %i[local www zip hidden_service].freeze
|
||||
DEPLOYS = %i[local private www zip hidden_service].freeze
|
||||
|
||||
validates :name, uniqueness: true, hostname: {
|
||||
allow_root_label: true
|
||||
|
|
|
@ -14,6 +14,11 @@ class SitePolicy
|
|||
true
|
||||
end
|
||||
|
||||
# Puede ver la versión privada del sitio?
|
||||
def private?
|
||||
edit? && site.deploys.find_by_type('DeployPrivate')
|
||||
end
|
||||
|
||||
# Todes les usuaries pueden ver el sitio si aceptaron la invitación
|
||||
def show?
|
||||
!current_role.temporal
|
||||
|
|
20
app/views/deploys/_deploy_private.haml
Normal file
20
app/views/deploys/_deploy_private.haml
Normal file
|
@ -0,0 +1,20 @@
|
|||
-# Formulario para alojar una copia privada
|
||||
|
||||
.row
|
||||
.col
|
||||
= deploy.hidden_field :id
|
||||
= deploy.hidden_field :type
|
||||
|
||||
.custom-control.custom-switch
|
||||
-#
|
||||
El checkbox invierte la lógica de destrucción porque queremos
|
||||
crear el deploy si está activado y destruirlo si está
|
||||
desactivado.
|
||||
= deploy.check_box :_destroy,
|
||||
{ checked: deploy.object.persisted?, class: 'custom-control-input' },
|
||||
'0', '1'
|
||||
= deploy.label :_destroy, class: 'custom-control-label' do
|
||||
%h3= t('.title')
|
||||
= sanitize_markdown t('.help'),
|
||||
tags: %w[p strong em a]
|
||||
%hr/
|
|
@ -17,8 +17,10 @@
|
|||
new_site_post_path(@site, layout: layout)
|
||||
|
||||
- if policy(@site).edit?
|
||||
= link_to t('sites.edit.btn', site: @site.title),
|
||||
edit_site_path(@site), class: 'btn'
|
||||
= link_to t('sites.edit.btn', site: @site.title), edit_site_path(@site), class: 'btn'
|
||||
|
||||
- if policy(@site).private?
|
||||
= link_to t('sites.private'), '../private/' + @site.name, class: 'btn', target: '_blank'
|
||||
|
||||
= render 'sites/build', site: @site
|
||||
|
||||
|
|
|
@ -71,6 +71,10 @@ en:
|
|||
title: Link to www
|
||||
success: Success!
|
||||
error: Error
|
||||
deploy_private:
|
||||
title: Private version
|
||||
success: Success!
|
||||
error: Error
|
||||
deploy_zip:
|
||||
title: Build ZIP file
|
||||
success: Available for download
|
||||
|
@ -255,6 +259,13 @@ en:
|
|||
We're working out the details for allowing your own site
|
||||
domains, you can help us!
|
||||
ejemplo: 'example'
|
||||
deploy_private:
|
||||
title: 'Generate private version'
|
||||
help: |
|
||||
Some templates support gathering private information. By
|
||||
enabling this option, when changes are published, you and your
|
||||
collaborators will be able to access this information in a
|
||||
private copy of the site.
|
||||
deploy_www:
|
||||
title: 'Add www to the address'
|
||||
help: |
|
||||
|
@ -337,6 +348,7 @@ en:
|
|||
title: 'Sites'
|
||||
enqueued: 'Waiting for build'
|
||||
enqueue: 'Publish all changes'
|
||||
private: 'Private version'
|
||||
failed: 'Failed!'
|
||||
build_log: 'Read log'
|
||||
invitations:
|
||||
|
|
|
@ -79,6 +79,10 @@ es:
|
|||
title: Alojar como servicio oculto de Tor
|
||||
success: ¡Éxito!
|
||||
error: Hubo un error
|
||||
deploy_private:
|
||||
title: Versión privada del sitio
|
||||
success: ¡Éxito!
|
||||
error: Hubo un error
|
||||
help: Por cualquier duda, responde este correo para contactarte con nosotres.
|
||||
maintenance_mailer:
|
||||
notice:
|
||||
|
@ -257,6 +261,13 @@ es:
|
|||
Estamos desarrollando la posibilidad de agregar tus propios
|
||||
dominios, ¡ayudanos!
|
||||
ejemplo: 'ejemplo'
|
||||
deploy_private:
|
||||
title: 'Generar versión privada'
|
||||
help: |
|
||||
Algunas plantillas contienen información privada, activando esta
|
||||
opción, al publicar los cambios podrás acceder a una versión
|
||||
privada del sitio, que solo estará accesible para todes les
|
||||
colaboradores del sitio.
|
||||
deploy_www:
|
||||
title: 'Agregar www a la dirección'
|
||||
help: |
|
||||
|
@ -339,6 +350,7 @@ es:
|
|||
title: 'Sitios'
|
||||
enqueued: 'Esperando publicación'
|
||||
enqueue: 'Publicar todos los cambios'
|
||||
private: 'Versión privada'
|
||||
failed: '¡Falló!'
|
||||
build_log: 'Ver registro'
|
||||
invitations:
|
||||
|
|
|
@ -26,9 +26,12 @@ Rails.application.routes.draw do
|
|||
end
|
||||
end
|
||||
|
||||
resources :sites, constraints: { site_id: %r{[^/]+}, id: %r{[^/]+} } do
|
||||
get 'public/:type/:basename', to: 'sites#send_public_file'
|
||||
# Las rutas privadas empiezan con una ruta única para poder hacer un
|
||||
# alias en nginx sin tener que usar expresiones regulares para
|
||||
# detectar el nombre del sitio.
|
||||
get '/sites/private/:site_id(*file)', to: 'private#show', constraints: { site_id: %r{[^/]+} }
|
||||
|
||||
resources :sites, constraints: { site_id: %r{[^/]+}, id: %r{[^/]+} } do
|
||||
# Gestionar actualizaciones del sitio
|
||||
get 'pull', to: 'sites#fetch'
|
||||
post 'pull', to: 'sites#merge'
|
||||
|
|
Loading…
Reference in a new issue