0

In my rails (4.2.3) blog app, I use ckeditor to create the body of the post. I use carrierwave with cloudinary as my repository. The blog allows multiple users to log in and create posts.

Here are the highlights of the code:

# Gems
gem 'ckeditor', github: 'galetahub/ckeditor'
gem 'mini_magick'
gem 'carrierwave'
gem 'cloudinary'

# Uploader
class CkeditorPictureUploader < CarrierWave::Uploader::Base
  include Ckeditor::Backend::CarrierWave
  include Cloudinary::CarrierWave
  include CarrierWave::MiniMagick

  [:extract_content_type, :set_size, :read_dimensions].each do |method|
     define_method :"#{method}_with_cloudinary" do
       send(:"#{method}_without_cloudinary") if self.file.is_a?(CarrierWave::SanitizedFile)
       {}
     end
     alias_method_chain method, :cloudinary
   end

# ckeditor/config.js
// The location of an external file browser, that should be launched when "Browse Server" button is pressed.
  config.filebrowserBrowseUrl = "/ckeditor/attachment_files";

  // The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Flash dialog.
  config.filebrowserFlashBrowseUrl = "/ckeditor/attachment_files";

  // The location of a script that handles file uploads in the Flash dialog.
  config.filebrowserFlashUploadUrl = "/ckeditor/attachment_files";

  // The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Link tab of Image dialog.
  config.filebrowserImageBrowseLinkUrl = "/ckeditor/pictures";

  // The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Image dialog.
  config.filebrowserImageBrowseUrl = "/ckeditor/pictures";

  // The location of a script that handles file uploads in the Image dialog.
  config.filebrowserImageUploadUrl = "/ckeditor/pictures";

  // The location of a script that handles file uploads.
  config.filebrowserUploadUrl = "/ckeditor/attachment_files";

  config.allowedContent = true;

# In the forms:
<%= f.cktext_area :body, class: 'form-control ckeditor' %>

So, bloggers are able to create posts containing images, and they are uploaded to cloudinary.

However, I want to restrict one user from seeing another user's image.

If user A creates a post containing image A, image A is uploaded to cloudinary. When user B logs in, and edits the body, if they click on the image button and click 'browse server', they can see image A. I would like each user to only see their own images.

User B can also delete user A's image A from the upload dialog. That is catastrophic in my scenario.

Is there any way to partition my cloudinary space for different users in the context of ckeditor/carrierwave?

The only option I saw was that cloudinary allows you to override the public id for each upload, which forms a url part. And I could set the public_id from the uploader to be each user's id:

def public_id
  return model.user.id
end

But I don't see how to use that to restrict access to those files only to that user from the uploader.

Another (pretty ugly) option is to remove the ckeditor->carrierwave->cloudinary integration entirely, and show my own "Upload image" button on top of each ckeditor text area, and when user clicks on it, only show their images in the modal popup. Once an image is uploaded/picked, I can (I think) then insert the image link into the cktextarea below it at the cursor position. I would have to reinvent the entire image resizing, etc. in my modal, since I cannot reuse the ones in the image dialog of ckeditor.

Anand
  • 3,690
  • 4
  • 33
  • 64
  • How do you provide the "browse server" dialog the list of available images? If this is done by first listing the images then you can use Tags or Folders to mutually exclude different users images. – Nadav Ofir Mar 08 '16 at 11:34
  • @NadavOfir - thanks a lot for your response. Yes, I would really like that, except I don't provide the list of images anywhere. My best guess is that it is provided by the file browser provided by the ckeditor gem's carrierwave backend. And somewhere between carrierwave gem and the cloudinary gem, all the images in the repository are being passed back. – Anand Mar 08 '16 at 12:34
  • 1
    I'm not familiar with this integration although I'm sure it can be changed/overridden. Find the query and change it to look for certain user-dedicated tags as well. Hope that helps. – Nadav Ofir Mar 09 '16 at 09:50
  • I looked for it a bit when I researched it - but didn't find any 'official' hooks in the gems I mentioned to upload with tags and to show based on tags - maybe we need to fork ckeditor and carrierwave and modify them to use tags... – Anand Mar 09 '16 at 12:24
  • Assigning tags when uploading to Cloudinary with Carrierwave is supported, see [here](http://cloudinary.com/documentation/rails_carrierwave#carrierwave_integration), don't know about ckeditor though. – Nadav Ofir Mar 10 '16 at 14:50
  • Yes, @Nadav Ofir - thanks again - I saw that - but as you rightly observe, there is no hook in the ckeditor context to call that... I can assign a tag as shown here (process tags: "my_user_id"), but I have no idea how to make ckeditor browse server dialog only show images tagged with the current user's id – Anand Mar 10 '16 at 15:26

0 Answers0