From 0dd63f6bf6c2023fcd6ff73338934d6c2dbe78ce Mon Sep 17 00:00:00 2001 From: Christoph Haas Date: Mon, 20 Aug 2018 19:32:34 +0200 Subject: [PATCH] Attempt to assign anonymous screenshots to logged-in user --- app/controllers/packages_controller.rb | 40 ++++++++----------- .../users/my_sessions_controller.rb | 23 +++++++++++ .../users/omniauth_callbacks_controller.rb | 2 + app/models/screenshot.rb | 1 + app/models/user.rb | 20 ++++++++++ app/views/layouts/_topbar.slim | 1 + config/routes.rb | 3 +- 7 files changed, 65 insertions(+), 25 deletions(-) create mode 100644 app/controllers/users/my_sessions_controller.rb diff --git a/app/controllers/packages_controller.rb b/app/controllers/packages_controller.rb index da81a2f..302d047 100644 --- a/app/controllers/packages_controller.rb +++ b/app/controllers/packages_controller.rb @@ -33,8 +33,7 @@ class PackagesController < ApplicationController # 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. - create_pseudo_user unless user_signed_in? - + # User.create_pseudo_user unless user_signed_in? @package = Package.find_by!(name: params[:name]) @valid_images = [] @invalid_images = [] @@ -57,16 +56,20 @@ class PackagesController < ApplicationController new_screenshot.user = current_user # Can the upload get approved automatically? - new_screenshot.approve! if current_user and current_user.auto_approve? + if current_user + new_screenshot.approve! if current_user.auto_approve? + + # For anonymous uploads remember which screenshots have been + # uploaded. If the user logs in later the screenshots will + # be linked to their account. + else + (session[:uploaded_screenshots] ||= []) << new_screenshot.id + Log.log "Anonymously uploaded screenshots #{new_screenshot.id} remembered in cookie session to assign it to a user later." + end new_screenshot.save Log.log "Screenshot #{new_screenshot.id} uploaded successfully from #{session[:ip]}. User has token #{session[:token]} or is #{current_user}" - if current_user.is_admin? - Log.log "Admin upload is automatically approved." - new_screenshot.approve_screenshot! - end - @valid_images.push new_screenshot else Log.log "Screenshot #{new_screenshot.image_file_name} invalid (#{new_screenshot.errors[:image]})." @@ -247,18 +250,7 @@ class PackagesController < ApplicationController # end private - - # Seamlessly create a user account for the current client. - # It helps track uploads. - def 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 - + # Send a dummy thumbnail reading "No screenshot available. Sorry." def thumbnail404 send_file Rails.root.join('public/images/dummy/thumbnail404.png'), @@ -298,10 +290,10 @@ class PackagesController < ApplicationController # Store a random identifier and the client's IP address in the session # for later identification. - def create_user_token - session[:token] ||= SecureRandom.hex - session[:ip] ||= request.remote_ip - end + # def create_user_token + # session[:token] ||= SecureRandom.hex + # session[:ip] ||= request.remote_ip + # end # Get reviews of this package from the Ubuntu API def get_ubuntu_reviews(packagename) diff --git a/app/controllers/users/my_sessions_controller.rb b/app/controllers/users/my_sessions_controller.rb new file mode 100644 index 0000000..4a41ced --- /dev/null +++ b/app/controllers/users/my_sessions_controller.rb @@ -0,0 +1,23 @@ +class Users::MySessionsController < Devise::SessionsController + # before_filter :before_login, :only => :create + after_filter :after_login, :only => :create + + # def before_login + # end + + # Hook after successful login + def after_login + Log.log "User #{current_user} logged in." + old_screenshots = session[:uploaded_screenshots] + raise + if count = old_screenshots.to_a.length > 0 + old_screenshots.each do |id| + ss = Screenshot.find(id) + ss.user = @user + ss.save! + end + flash[:info] = "#{count} uploads have been added to your account" + Log.log "Anonymously uploaded screenshots #{old_screenshots} added to account." + end + end +end diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb index 22de0b4..e36f6fd 100644 --- a/app/controllers/users/omniauth_callbacks_controller.rb +++ b/app/controllers/users/omniauth_callbacks_controller.rb @@ -33,6 +33,8 @@ class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController # You need to implement the method below in your model (e.g. app/models/user.rb) @user = User.from_omniauth(request.env["omniauth.auth"]) + # Has the user uploaded screenshots while not being logged in? + # Move the screenshots to the real account and tell the user. if @user.persisted? flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => provider_name sign_in_and_redirect @user, :event => :authentication diff --git a/app/models/screenshot.rb b/app/models/screenshot.rb index 98d36ad..7d64166 100644 --- a/app/models/screenshot.rb +++ b/app/models/screenshot.rb @@ -2,6 +2,7 @@ class Screenshot < ApplicationRecord belongs_to :package, inverse_of: :screenshots belongs_to :user, inverse_of: :screenshots + # Use paperclip gem to handle image files related to screenshots has_attached_file :image, styles: { :large => '800x600>', :thumb => '160x120>' }, default_url: '/images/dummy/no-screenshots-available.svg', diff --git a/app/models/user.rb b/app/models/user.rb index 9da70e8..f189f46 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -52,6 +52,9 @@ class User < ApplicationRecord # 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? @@ -75,4 +78,21 @@ class User < ApplicationRecord user.password = Devise.friendly_token[0,20] end end + + # Seamlessly create a user account for the current client. + # 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. end diff --git a/app/views/layouts/_topbar.slim b/app/views/layouts/_topbar.slim index 4500287..5424379 100644 --- a/app/views/layouts/_topbar.slim +++ b/app/views/layouts/_topbar.slim @@ -1,3 +1,4 @@ += session[:uploaded_screenshots].inspect nav.top-bar .grid-container style="flex-grow:1;" // https://foundation.zurb.com/forum/posts/53446-top-bar-and-xy-grid diff --git a/config/routes.rb b/config/routes.rb index 72e9d11..0358902 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -9,7 +9,8 @@ Rails.application.routes.draw do devise_for :users, controllers: { # registrations: "users/registrations", # passwords: "users/passwords", - omniauth_callbacks: "users/omniauth_callbacks" + omniauth_callbacks: "users/omniauth_callbacks", + sessions: "users/my_sessions" } get 'packages' => 'packages#grid', as: :packages_grid