Authorisation management using CanCanCan added
This commit is contained in:
parent
51be4a4777
commit
7a3b65fe50
24 changed files with 211 additions and 295 deletions
3
Gemfile
3
Gemfile
|
|
@ -143,3 +143,6 @@ gem 'omniauth_openid_connect'
|
|||
# Mitigate CVE-2015-9284
|
||||
# https://github.com/cookpad/omniauth-rails_csrf_protection
|
||||
gem 'omniauth-rails_csrf_protection'
|
||||
|
||||
# Role-based access
|
||||
gem 'cancancan'
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ GEM
|
|||
msgpack (~> 1.0)
|
||||
builder (3.2.4)
|
||||
byebug (11.1.3)
|
||||
cancancan (3.2.1)
|
||||
capybara (3.35.3)
|
||||
addressable
|
||||
mini_mime (>= 0.1.3)
|
||||
|
|
@ -430,6 +431,7 @@ DEPENDENCIES
|
|||
bootsnap
|
||||
byebug
|
||||
bzip2-ruby!
|
||||
cancancan
|
||||
capybara
|
||||
cookies_eu
|
||||
devise
|
||||
|
|
|
|||
|
|
@ -1,38 +1,38 @@
|
|||
class AdminController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
before_action :admin_only
|
||||
# before_action :authenticate_user!
|
||||
# before_action :admin_only
|
||||
|
||||
def status
|
||||
end
|
||||
# def status
|
||||
# end
|
||||
|
||||
def screenshots
|
||||
end
|
||||
# def screenshots
|
||||
# end
|
||||
|
||||
def integration
|
||||
end
|
||||
# def integration
|
||||
# end
|
||||
|
||||
def moderate_list
|
||||
end
|
||||
# def moderate_list
|
||||
# end
|
||||
|
||||
def logs
|
||||
logs = Log
|
||||
# def logs
|
||||
# logs = Log
|
||||
|
||||
if params[:search].present?
|
||||
logger.debug "Searching for #{params[:search]}"
|
||||
logs = logs.where("message ilike ?", "%#{params[:search]}%")
|
||||
end
|
||||
# if params[:search].present?
|
||||
# logger.debug "Searching for #{params[:search]}"
|
||||
# logs = logs.where("message ilike ?", "%#{params[:search]}%")
|
||||
# end
|
||||
|
||||
@logs = logs.paginate(page: params[:page], per_page: 20)
|
||||
end
|
||||
# @logs = logs.paginate(page: params[:page], per_page: 20)
|
||||
# end
|
||||
|
||||
|
||||
private
|
||||
# private
|
||||
|
||||
def admin_only
|
||||
unless current_user.is_admin?
|
||||
head :forbidden
|
||||
# redirect_to :back, :alert => "Access denied."
|
||||
end
|
||||
end
|
||||
# def admin_only
|
||||
# unless current_user.is_admin?
|
||||
# head :forbidden
|
||||
# # redirect_to :back, :alert => "Access denied."
|
||||
# end
|
||||
# end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class ApplicationController < ActionController::Base
|
|||
# the navigation bar that contains a paginator of packages that contain
|
||||
# screenshots that require moderation.
|
||||
def moderate_packages
|
||||
if user_signed_in? and current_user.is_admin? and Package.need_moderation.any?
|
||||
if can? :approve, Screenshot and Package.need_moderation.any?
|
||||
@moderate_packages = Package.need_moderation
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,27 +1,22 @@
|
|||
class ModerateController < ApplicationController
|
||||
# class ModerateController < ApplicationController
|
||||
|
||||
before_action :authenticate_user!
|
||||
# before_action :authenticate_user!
|
||||
|
||||
def index
|
||||
# First package with pending screenshots
|
||||
@package = Package.joins(:screenshots).where('screenshots.approved=false or screenshots.markedfordelete=true').distinct(:name).first
|
||||
# def index
|
||||
# # First package with pending screenshots
|
||||
# @package = Package.joins(:screenshots).where('screenshots.approved=false').distinct(:name).first
|
||||
|
||||
# # List of screenshots that were reported (to be removed)
|
||||
# @reported_screenshots = Screenshot.where(markedfordelete: true)
|
||||
# # First package with reported screenshots
|
||||
# @reported_package = Package.joins(:screenshots).where('screenshots.markedfordelete=true').distinct(:name).first
|
||||
# if @package
|
||||
# # List of screenshots to be moderated
|
||||
# @pending_screenshots = @package.screenshots_pending
|
||||
# # Number of screenshots that were already moderated (during this session)
|
||||
# session[:already_moderated] ||= 0
|
||||
# @moderated_screenshots = session[:already_moderated]
|
||||
|
||||
if @package
|
||||
# List of screenshots to be moderated
|
||||
@pending_screenshots = @package.screenshots_pending
|
||||
# Number of screenshots that were already moderated (during this session)
|
||||
session[:already_moderated] ||= 0
|
||||
@moderated_screenshots = session[:already_moderated]
|
||||
|
||||
# BUG: calculation is wrong when pending and reported screenshots are in the queue
|
||||
# Percentage of already moderated screenshots
|
||||
@percent_moderated = 100 * (@moderated_screenshots+1) / (@moderated_screenshots + @pending_screenshots.count)
|
||||
# @percent_moderated = 100 * (@moderated_screenshots+1) / (@moderated_screenshots + @pending_screenshots.count + @reported_screenshots.count)
|
||||
end
|
||||
end
|
||||
end
|
||||
# # BUG: calculation is wrong when pending and reported screenshots are in the queue
|
||||
# # Percentage of already moderated screenshots
|
||||
# @percent_moderated = 100 * (@moderated_screenshots+1) / (@moderated_screenshots + @pending_screenshots.count)
|
||||
# # @percent_moderated = 100 * (@moderated_screenshots+1) / (@moderated_screenshots + @pending_screenshots.count + @reported_screenshots.count)
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
|
|
|
|||
|
|
@ -37,10 +37,6 @@ class PackagesController < ApplicationController
|
|||
# This action saves the screenshots already if they are valid. The user is
|
||||
# then given the chance to comment on and delete the screenshots again.
|
||||
def upload_receive
|
||||
# Create a pseudo user account for the user.
|
||||
# The user won't know that an account is created.
|
||||
# But this makes it easier to track who screenshots belong to.
|
||||
# User.create_pseudo_user unless user_signed_in?
|
||||
@package = Package.find_by!(name: params[:name])
|
||||
@valid_images = []
|
||||
@invalid_images = []
|
||||
|
|
@ -65,7 +61,7 @@ class PackagesController < ApplicationController
|
|||
|
||||
# Check if the image was valid
|
||||
if new_screenshot.valid?
|
||||
new_screenshot.uploaderhash = session.id.to_s
|
||||
# new_screenshot.uploaderhash = session.id.to_s
|
||||
new_screenshot.uploaderip = request.remote_ip
|
||||
new_screenshot.version = @package.version
|
||||
# ActiveStorage does not yet create a file checksum automatically.
|
||||
|
|
@ -77,19 +73,25 @@ class PackagesController < ApplicationController
|
|||
Log.log "Duplicate image with fingerprint #{new_screenshot.image_fingerprint} found. Rejecting."
|
||||
all_errors << "Your file #{img.original_filename} is a duplicate. Sorry."
|
||||
else
|
||||
# Can the upload get approved automatically?
|
||||
if user_signed_in?
|
||||
new_screenshot.user = current_user
|
||||
new_screenshot.approve! if auto_approve?
|
||||
end
|
||||
# TODO: Can the upload get approved automatically?
|
||||
|
||||
# Create a pseudo user account for the user.
|
||||
# The user won't know that an account is created.
|
||||
# But this makes it easier to track who screenshots belong to.
|
||||
unless user_signed_in?
|
||||
sign_in User.create_pseudo_user
|
||||
end
|
||||
new_screenshot.user = current_user
|
||||
new_screenshot.approve! if can?(:approve, new_screenshot)
|
||||
|
||||
# Pre-render screenshot in different sizes
|
||||
new_screenshot.simage_derivatives!
|
||||
Log.log "Derivatives created"
|
||||
|
||||
new_screenshot.save!
|
||||
Log.log "Screenshot #{new_screenshot.id} uploaded successfully. " + \
|
||||
"ip=#{new_screenshot.uploaderip}. "+ \
|
||||
"user-hash=#{new_screenshot.uploaderhash}. "+ \
|
||||
#"user-hash=#{new_screenshot.uploaderhash}. "+ \
|
||||
"user-name=#{current_user} "+ \
|
||||
"image-fingerprint=#{new_screenshot.image_fingerprint} "+ \
|
||||
"image-path=#{img.path}"
|
||||
|
|
@ -174,7 +176,7 @@ class PackagesController < ApplicationController
|
|||
|
||||
# Check if the user is allowed to change this screenshot
|
||||
# - Is this the user's own screenshot? (anonymous)
|
||||
if @screenshot.user == current_user or current_user.is_admin?
|
||||
if (@screenshot.user == current_user) || (can? :detroy, @screenshot)
|
||||
logger.debug "User #{current_user} deletes screenshot #{@screenshot}"
|
||||
@screenshot.destroy
|
||||
flash['notice'] = "Screenshot deleted."
|
||||
|
|
@ -185,8 +187,9 @@ class PackagesController < ApplicationController
|
|||
end
|
||||
|
||||
def approve_screenshot
|
||||
if current_user && current_user.is_admin?
|
||||
@screenshot = Screenshot.find(params[:id])
|
||||
@screenshot = Screenshot.find(params[:id])
|
||||
|
||||
if can? :approve, @screenshot
|
||||
@screenshot.approve!
|
||||
flash['notice'] = "Screenshot approved."
|
||||
redirect_back(fallback_location: package_path(name: @screenshot.package.name))
|
||||
|
|
@ -263,23 +266,6 @@ class PackagesController < ApplicationController
|
|||
redirect_back(fallback_location: package_path(name: @screenshot.package.name))
|
||||
end
|
||||
|
||||
# Receive an anonymous report from a user to have a screenshot removed.
|
||||
# def report_screenshot
|
||||
# @screenshot = Screenshot.find(params[:id])
|
||||
# # if verify_recaptcha
|
||||
# @screenshot.delete_reason = params[:delete_reason]
|
||||
# @screenshot.markedfordelete = true
|
||||
# if @screenshot.valid?
|
||||
# @screenshot.save!
|
||||
# flash['notice'] = "Screenshot reported. The moderators will deal with it."
|
||||
# else
|
||||
# errors = @screenshot.errors.to_a.join(' and ')
|
||||
# flash['alert'] = "Sorry. #{errors}"
|
||||
# end
|
||||
# # end
|
||||
# redirect_back(fallback_location: package_path)
|
||||
# end
|
||||
|
||||
# Show an HTML partial with reviews of this package from the Ubuntu API
|
||||
# def reviews
|
||||
# expires_in 1.day, public: true
|
||||
|
|
@ -350,37 +336,7 @@ class PackagesController < ApplicationController
|
|||
params.require(:screenshot).permit(:description)
|
||||
end
|
||||
|
||||
# Do uploads from this user get approved automatically?
|
||||
def auto_approve?
|
||||
# Anonymous users need to go through moderation
|
||||
return false unless user_signed_in?
|
||||
|
||||
# Admins do not need moderation
|
||||
return true if current_user.is_admin?
|
||||
|
||||
# Debian developers do not need moderation
|
||||
return true if current_user.provider == 'debian-sso'
|
||||
|
||||
# After one successfully approved screenshot users do not need moderation
|
||||
# return true if current_user.approved_screenshots.count > 0
|
||||
|
||||
# Any other user's upload must be moderated
|
||||
return false
|
||||
end
|
||||
|
||||
def screenshots_visible_to_user(package)
|
||||
if user_signed_in? and current_user.is_admin?
|
||||
# User is an admin and can view all screenshots
|
||||
package.screenshots
|
||||
# TODO: User logins and assigned screenshots will come in a later version
|
||||
# elsif user_signed_in?
|
||||
# package.screenshots.where(id: (current_user.screenshots.select(:id))) | \
|
||||
# package.screenshots.where(approved: true).order('created_at DESC')
|
||||
else
|
||||
package.screenshots.where(uploaderhash: session.id.to_s).or(
|
||||
package.screenshots.where(approved: true)
|
||||
)
|
||||
.order('created_at DESC')
|
||||
end
|
||||
package.screenshots.accessible_by(current_ability, :view).order('created_at DESC')
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,45 +1,5 @@
|
|||
module PackagesHelper
|
||||
|
||||
# Return a query of all screenshots that the current user may see
|
||||
# Consists of:
|
||||
# - approved (public) screenshots
|
||||
# - screenshots uploaded by the user
|
||||
# - all screenshots if the user is an admin
|
||||
# def screenshots_visible_to_user(package)
|
||||
# if user_signed_in? and current_user.is_admin?
|
||||
# # User is an admin and can view all screenshots
|
||||
# package.screenshots
|
||||
# # TODO: User logins and assigned screenshots will come in a later version
|
||||
# # elsif user_signed_in?
|
||||
# # package.screenshots.where(id: (current_user.screenshots.select(:id))) | \
|
||||
# # package.screenshots.where(approved: true).order('created_at DESC')
|
||||
# else
|
||||
# package.screenshots.where(uploaderhash: session.id.to_s) | \
|
||||
# package.screenshots.where(approved: true).order('created_at DESC')
|
||||
# end
|
||||
# end
|
||||
|
||||
def screenshots_visible_to_user(package, user_session)
|
||||
# Show all screenshots to admins
|
||||
if current_user && current_user.is_admin?
|
||||
package.screenshots
|
||||
|
||||
# Show screenshots belonging to the user or public/approved
|
||||
else
|
||||
package.screenshots.where(
|
||||
uploaderhash: user_session.id.to_s
|
||||
).or(
|
||||
package.screenshots.where(
|
||||
approved: true
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def screenshot_uploaded_by_current_user?(screenshot)
|
||||
screenshot.uploaderhash == session.id.to_s
|
||||
end
|
||||
|
||||
# Return the description and/or the version of the package
|
||||
def screenshot_caption(screenshot)
|
||||
str = []
|
||||
|
|
@ -78,9 +38,7 @@ module PackagesHelper
|
|||
|
||||
def status_text(screenshot)
|
||||
# TODO: markedfordelete/reporting will be removed
|
||||
if screenshot.markedfordelete
|
||||
"Removal requested > #{screenshot.delete_reason}"
|
||||
elsif screenshot.approved
|
||||
if screenshot.approved
|
||||
fa_icon('check-square') + ' Public'
|
||||
else
|
||||
fa_icon('hourglass') + ' Waiting for approval'
|
||||
|
|
|
|||
56
app/models/ability.rb
Normal file
56
app/models/ability.rb
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Ability
|
||||
include CanCan::Ability
|
||||
|
||||
def initialize(user)
|
||||
|
||||
# Define abilities for the passed in user here. For example:
|
||||
#
|
||||
# user ||= User.new # guest user (not logged in)
|
||||
# if user.admin?
|
||||
# can :manage, :all
|
||||
# else
|
||||
# can :read, :all
|
||||
# end
|
||||
#
|
||||
# The first argument to `can` is the action you are giving the user
|
||||
# permission to do.
|
||||
# If you pass :manage it will apply to every action. Other common actions
|
||||
# here are :read, :create, :update and :destroy.
|
||||
#
|
||||
# The second argument is the resource the user can perform the action on.
|
||||
# If you pass :all it will apply to every resource. Otherwise pass a Ruby
|
||||
# class of the resource.
|
||||
#
|
||||
# The third argument is an optional hash of conditions to further filter the
|
||||
# objects.
|
||||
# For example, here the user can only update published articles.
|
||||
#
|
||||
# can :update, Article, :published => true
|
||||
#
|
||||
# See the wiki for details:
|
||||
# https://github.com/CanCanCommunity/cancancan/wiki/Defining-Abilities
|
||||
|
||||
if user.present? # Logged-in users
|
||||
if user.admin_role?
|
||||
can :approve, Screenshot
|
||||
can :destroy, Screenshot
|
||||
can :destroy, User
|
||||
can :view, Screenshot
|
||||
can :destroy, Package
|
||||
end
|
||||
if user.moderator_role?
|
||||
can :approve, Screenshot
|
||||
can :view, Screenshot
|
||||
can :destroy, Screenshot
|
||||
end
|
||||
if user.pseudo?
|
||||
# Allow to view all public/approved screenshots
|
||||
can :view, Screenshot, approved: true
|
||||
# Allow to view any own uploads (even not-yet-approved)
|
||||
can :view, Screenshot, user_id: user.id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -53,7 +53,7 @@ class Package < ApplicationRecord
|
|||
|
||||
# Return a list of packages that have screenshots to be moderated
|
||||
def self.need_moderation
|
||||
Package.joins(:screenshots).where('screenshots.approved=false or screenshots.markedfordelete=true').distinct(:name)
|
||||
Package.joins(:screenshots).where('screenshots.approved=false').distinct(:name)
|
||||
end
|
||||
|
||||
|
||||
|
|
@ -71,7 +71,7 @@ class Package < ApplicationRecord
|
|||
|
||||
# Return a query of all approved/public screenshots of this package
|
||||
def screenshots_pending
|
||||
self.screenshots.where('approved=false or markedfordelete=true')
|
||||
self.screenshots.where('approved=false')
|
||||
end
|
||||
|
||||
# Return a list of packages that have unapproved screenshots
|
||||
|
|
|
|||
|
|
@ -10,11 +10,6 @@ class Screenshot < ApplicationRecord
|
|||
# Shrine
|
||||
include ImageUploader::Attachment(:simage) # adds an `simage` virtual attribute
|
||||
|
||||
# Calculate how many days ago this screenshot has been uploaded
|
||||
def age
|
||||
time_ago_in_words(self.created_at)
|
||||
end
|
||||
|
||||
# Return caption for full-screen screenshots.
|
||||
# Takes the description of a screenshot if available.
|
||||
# Otherwise it falls back to the general description of its package.
|
||||
|
|
@ -54,19 +49,16 @@ class Screenshot < ApplicationRecord
|
|||
|
||||
# Brief text describing the status of this screenshots (for admins)
|
||||
def adminstatus
|
||||
if self.markedfordelete
|
||||
"Removal requested > #{self.delete_reason}"
|
||||
elsif self.approved
|
||||
if self.approved
|
||||
'Public'
|
||||
else
|
||||
fa_icon('hourglass') + 'Waiting for approval'
|
||||
#fa_icon('hourglass') + 'Waiting for approval'
|
||||
'Waiting for approval'
|
||||
end
|
||||
end
|
||||
|
||||
# Publish a screenshot from the moderation queue
|
||||
def approve!
|
||||
self.delete_reason = nil
|
||||
self.markedfordelete = false
|
||||
self.approved = true
|
||||
self.save!
|
||||
end
|
||||
|
|
@ -76,35 +68,6 @@ class Screenshot < ApplicationRecord
|
|||
self.order(created_at: :desc).where(approved: true).first
|
||||
end
|
||||
|
||||
# Returns true if the current user has administrative permissions
|
||||
# def can_admin?
|
||||
# self.admin == 1
|
||||
# end
|
||||
|
||||
# Returns true if the current user can upload screenshots without moderation
|
||||
# def can_upload_without_moderation?
|
||||
# # Admins can upload without moderation
|
||||
# true if self.can_admin
|
||||
|
||||
# # Authenticated users with at least one approved screenshot
|
||||
# #true if self.screenshots.where(approved: true).count >= 1
|
||||
|
||||
# # Other visitors require moderation
|
||||
# false
|
||||
# end
|
||||
|
||||
# Returns true if the current user can delete screenshots
|
||||
# def can_delete?
|
||||
# # Admins can delete screenshots
|
||||
# true if self.can_admin
|
||||
|
||||
# # Authenticated users with at least one approved screenshot
|
||||
# #true if self.screenshots.where(approved: true).count >= 1
|
||||
|
||||
# # Other visitors require moderation
|
||||
# false
|
||||
# end
|
||||
|
||||
# Return the part of the version up to the first - or +
|
||||
def upstream_version
|
||||
self.version.split(/[\-\+]/).first
|
||||
|
|
|
|||
|
|
@ -40,10 +40,6 @@ class User < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
def is_admin?
|
||||
self.admin == 1
|
||||
end
|
||||
|
||||
# Check if a user has been created on-the-fly and is just an
|
||||
# anonymous user who uploaded a screenshot. They can turn this
|
||||
# user record into a registered account though.
|
||||
|
|
@ -59,6 +55,11 @@ class User < ApplicationRecord
|
|||
user.name = auth.info.name
|
||||
# Set a random password
|
||||
user.password = Devise.friendly_token[0,20]
|
||||
|
||||
# Users coming through salsa.debian.net/OpenID-Connect will get moderator role
|
||||
if user.email.end_with?('@debian.org') && user.provider=='salsa'
|
||||
user.moderator_role = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -66,20 +67,18 @@ class User < ApplicationRecord
|
|||
self.screenshots.where(approved: true)
|
||||
end
|
||||
|
||||
# Seamlessly create a user account for the current client.
|
||||
# Seamlessly create a user account for the current visitor.
|
||||
# It helps track uploads because uploaded screenshots get assigned
|
||||
# to this user record. The user can later decide to use a real
|
||||
# account and get their screenshots transferred to that.
|
||||
# def self.create_pseudo_user
|
||||
# generated_password = Devise.friendly_token.first(8)
|
||||
# new_user = User.create(
|
||||
# name: 'Anonymous',
|
||||
# password: generated_password)
|
||||
# Log.log "New pseudo user for anonymous upload created: #{new_user}"
|
||||
# sign_in new_user
|
||||
# end
|
||||
#
|
||||
# Currently the approach is different: do not create an account
|
||||
# for a user. Instead store the IDs of the uploaded screenshots
|
||||
# and transfer them if the user decides to do a real login using SSO.
|
||||
# to this user record.
|
||||
# TODO: The user can later decide to use a real account and get their screenshots transferred to that.
|
||||
def self.create_pseudo_user
|
||||
generated_password = Devise.friendly_token.first(8)
|
||||
new_user = User.create(
|
||||
name: 'Anonymous',
|
||||
password: generated_password,
|
||||
pseudo: true
|
||||
)
|
||||
Log.log "New pseudo user for anonymous upload created: #{new_user}"
|
||||
return new_user
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -15,6 +15,3 @@
|
|||
/ ' | Cookie is #{session[:token]}
|
||||
|
||||
= render 'cookies_eu/consent_banner', link: '/about#cookies'
|
||||
|
||||
/ = current_user.is_admin?
|
||||
/ = session.id
|
||||
|
|
|
|||
|
|
@ -31,12 +31,6 @@
|
|||
a.button.alert.round href=delete_screenshot_path(screenshot) onclick="return confirm('Really delete the screenshot?');" Reject
|
||||
a.button.success.round href=approve_screenshot_path(screenshot) Approve
|
||||
|
||||
/ Existing screenshots that was requested for removal
|
||||
- if screenshot.markedfordelete==true
|
||||
.button-group
|
||||
a.button.alert.round href=delete_screenshot_path(screenshot) onclick="return confirm('Really delete the screenshot?');" Remove as requested
|
||||
a.button.success.round href=approve_screenshot_path(screenshot) Keep the screenshot
|
||||
|
||||
|
||||
.small-6.cell
|
||||
p Existing screenshots:
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@
|
|||
= link_to moderate_list_path
|
||||
= fa_icon 'check 2x', text: 'Moderate'
|
||||
// Add link if user has uploaded screenshots
|
||||
- if @current_users_screenshots and @current_users_screenshots.any?
|
||||
li class=('active' if controller_name=='my' and action_name=='uploads')
|
||||
= link_to my_uploads_path
|
||||
= fa_icon 'image 2x', text: 'My uploads'
|
||||
' My uploads
|
||||
/ - if @current_users_screenshots and @current_users_screenshots.any?
|
||||
/ li class=('active' if controller_name=='my' and action_name=='uploads')
|
||||
/ = link_to my_uploads_path
|
||||
/ = fa_icon 'image 2x', text: 'My uploads'
|
||||
/ ' My uploads
|
||||
|
||||
li
|
||||
= link_to destroy_user_session_path, method: :delete
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@
|
|||
h2 Number of screenshots you uploaded
|
||||
p = current_user.screenshots.count
|
||||
|
||||
- if current_user.is_admin?
|
||||
h2 Admin
|
||||
p Apparently you are an administrator. Be careful with that thing!
|
||||
|
||||
tt = current_user.inspect
|
||||
/ - if current_user.is_admin?
|
||||
/ h2 Admin
|
||||
/ p Apparently you are an administrator. Be careful with that thing!
|
||||
/ - you can moderate
|
||||
/ - you can …
|
||||
|
|
@ -16,8 +16,8 @@
|
|||
- @current_users_screenshots.each do |screenshot|
|
||||
.column
|
||||
/ TODO: old Paperclip style
|
||||
a.black.fancybox href=screenshot.image.variant(resize_to_limit: [800,600], timestamp: false)
|
||||
a.black.fancybox href=screenshot.simage_url(:large)
|
||||
div.grid-thumbnail
|
||||
= image_tag(screenshot.image.variant(resize_to_limit: [160,120]), alt: screenshot.caption, class: 'thumbnail')
|
||||
= image_tag(screenshot.simage_url(:medium), alt: screenshot.caption, class: 'thumbnail')
|
||||
div
|
||||
= screenshot.description
|
||||
|
|
|
|||
|
|
@ -1,7 +1,13 @@
|
|||
// Button that reveals a dropdown/modal for moderation/reporting
|
||||
|
||||
- if can?(:destroy, screenshot) || can?(:approve, screenshot)
|
||||
.text
|
||||
span.label.secondary
|
||||
= status_text(screenshot)
|
||||
|
||||
.button-group.small.align-center
|
||||
|
||||
- if (screenshot_uploaded_by_current_user?(screenshot) || (current_user && current_user.is_admin?))
|
||||
- if can?(:destroy, screenshot)
|
||||
a.button.small.bordered.radius.alert[
|
||||
href=delete_screenshot_path(screenshot.id)
|
||||
onclick="return confirm('Really delete the screenshot?');"
|
||||
|
|
@ -15,29 +21,15 @@
|
|||
/ href='#'
|
||||
/ ] #{fa_icon 'star'} Make primary
|
||||
|
||||
- if not screenshot.approved
|
||||
- if current_user && current_user.is_admin?
|
||||
- unless screenshot.approved
|
||||
- if can?(:approve, screenshot)
|
||||
a.button.small.success[
|
||||
href=approve_screenshot_path(screenshot.id)
|
||||
method='post'
|
||||
] Approve
|
||||
|
||||
/ - elsif screenshot.markedfordelete
|
||||
/ a.button.small.success[
|
||||
/ href=approve_screenshot_path(screenshot.id)
|
||||
/ method='post'
|
||||
/ ] Keep
|
||||
|
||||
] #{fa_icon 'check'} Approve
|
||||
|
||||
/ Display additional information to admins
|
||||
p Status: #{screenshot.adminstatus}
|
||||
p Uploader IP=#{screenshot.uploaderip}
|
||||
p Uploader Token=#{session[:token]}
|
||||
p Uploaded #{screenshot.age} ago (#{screenshot.created_at})
|
||||
|
||||
/ TODO: Move reporting screenshots to an extra page with a form and captcha
|
||||
/ - else
|
||||
/ / Allow anonymous users to report inappropriate screenshots
|
||||
/ = form_tag(report_screenshot_path(screenshot.id))
|
||||
/ = text_area_tag 'delete_reason', nil, class: 'input-group-field', maxlength: 100, rows: 3, cols: 50
|
||||
/ = submit_tag 'Request removal', class: 'button alert'
|
||||
/ p Status: #{screenshot.adminstatus}
|
||||
/ p Uploader IP=#{screenshot.uploaderip}
|
||||
/ p Uploader Token=#{session[:token]}
|
||||
/ p Uploaded #{time_ago_in_words(screenshot.created_at)} ago (#{screenshot.created_at})
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
// Button that reveals a dropdown/modal for users (for their own screenshots)
|
||||
.text-right
|
||||
button.small.dropdown.warning.button type="button" data-toggle="admin-info-#{screenshot.id}"
|
||||
'Request removal
|
||||
.dropdown-pane data-dropdown=true id="admin-info-#{screenshot.id}"
|
||||
p If you think this screenshot does not meet the guidelines
|
||||
or is misleading or not useful then please report it so that
|
||||
the moderators can review it. Just let us know why you think
|
||||
the screenshot should get removed:
|
||||
= form_tag(report_screenshot_path(screenshot.id))
|
||||
= text_area_tag 'delete_reason', nil, class: 'input-group-field', maxlength: 100, rows: 3, cols: 50
|
||||
= submit_tag 'Request removal', class: 'button alert'
|
||||
|
|
@ -25,24 +25,13 @@
|
|||
.text
|
||||
= screenshot.caption
|
||||
// Has the unmoderated screenshot been uploaded by the current user?
|
||||
- if screenshot_uploaded_by_current_user?(screenshot)
|
||||
- if current_user.screenshots.include?(screenshot)
|
||||
.text
|
||||
span.label.secondary
|
||||
' Uploaded by you
|
||||
- unless screenshot.approved
|
||||
' (needs to be approved)
|
||||
= render(partial: 'admin_buttons', locals: {screenshot: screenshot})
|
||||
// Is the user an admin?
|
||||
// or does the screenshot belong to the user (determined by session cookie)
|
||||
- if current_user && current_user.is_admin?
|
||||
hr
|
||||
.text
|
||||
span.label.secondary
|
||||
= status_text(screenshot)
|
||||
|
||||
= render(partial: 'admin_buttons', locals: {screenshot: screenshot})
|
||||
/ - elsif user_signed_in? and screenshot.user == current_user
|
||||
/ = render(partial: 'user_dropdown', locals: {screenshot: screenshot})
|
||||
= render(partial: 'admin_buttons', locals: {screenshot: screenshot})
|
||||
|
||||
|
||||
// Second paginator at the bottom so the user does not have to scroll up again
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
class DropDeprecatedScreenshotsFields < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
remove_column :screenshots, :markedfordelete
|
||||
remove_column :screenshots, :delete_reason
|
||||
remove_column :screenshots, :image_file_name
|
||||
remove_column :screenshots, :image_content_type
|
||||
remove_column :screenshots, :image_file_size
|
||||
remove_column :screenshots, :image_updated_at
|
||||
end
|
||||
end
|
||||
14
db/migrate/20210228100636_add_roles_to_users.rb
Normal file
14
db/migrate/20210228100636_add_roles_to_users.rb
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# Rename the :admin field to :admin_role and change integer to boolean
|
||||
class AddRolesToUsers < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
add_column :users, :admin_role, :boolean, default: false
|
||||
|
||||
User.find_each do |user|
|
||||
user.admin_role=true if user.admin>0
|
||||
user.save!
|
||||
end
|
||||
|
||||
remove_column :users, :admin
|
||||
add_column :users, :moderator_role, :boolean, default: false
|
||||
end
|
||||
end
|
||||
8
db/migrate/20210228191717_add_pseudo_column_to_user.rb
Normal file
8
db/migrate/20210228191717_add_pseudo_column_to_user.rb
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# Create a pseudo flag for accounts that get automatically created.
|
||||
# If an anonymous visitor uploads a screenshot he will get a
|
||||
# pseudo account to assign the screenshots to.
|
||||
class AddPseudoColumnToUser < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
add_column :users, :pseudo, :boolean, default: false
|
||||
end
|
||||
end
|
||||
12
db/schema.rb
12
db/schema.rb
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2021_02_22_102719) do
|
||||
ActiveRecord::Schema.define(version: 2021_02_28_191717) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
|
@ -88,14 +88,8 @@ ActiveRecord::Schema.define(version: 2021_02_22_102719) do
|
|||
t.datetime "created_at"
|
||||
t.string "uploaderhash", limit: 72
|
||||
t.boolean "approved", default: false, null: false
|
||||
t.boolean "markedfordelete"
|
||||
t.string "delete_reason", limit: 100
|
||||
t.text "description"
|
||||
t.datetime "updated_at"
|
||||
t.string "image_file_name"
|
||||
t.string "image_content_type"
|
||||
t.integer "image_file_size"
|
||||
t.datetime "image_updated_at"
|
||||
t.string "image_fingerprint"
|
||||
t.integer "user_id", default: 0
|
||||
t.text "simage_data"
|
||||
|
|
@ -120,7 +114,9 @@ ActiveRecord::Schema.define(version: 2021_02_22_102719) do
|
|||
t.datetime "locked_at"
|
||||
t.string "provider"
|
||||
t.string "uid"
|
||||
t.integer "admin", default: 0
|
||||
t.boolean "admin_role", default: false
|
||||
t.boolean "moderator_role", default: false
|
||||
t.boolean "pseudo", default: false
|
||||
t.index ["email", "provider"], name: "index_users_on_email_and_provider", unique: true
|
||||
end
|
||||
|
||||
|
|
|
|||
4
test/fixtures/screenshots.yml
vendored
4
test/fixtures/screenshots.yml
vendored
|
|
@ -6,8 +6,6 @@
|
|||
# uploaderhash: MyString
|
||||
# uploaderip: MyString
|
||||
# approved:
|
||||
# markedfordelete:
|
||||
# delete_reason: MyString
|
||||
# description: MyString
|
||||
|
||||
# two:
|
||||
|
|
@ -16,6 +14,4 @@
|
|||
# uploaderhash: MyString
|
||||
# uploaderip: MyString
|
||||
# approved:
|
||||
# markedfordelete:
|
||||
# delete_reason: MyString
|
||||
# description: MyString
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue