Class: Bcms::WebDAV::Resource

Inherits:
DAV4Rack::Resource
  • Object
show all
Includes:
DAV4Rack::HTTPStatus
Defined in:
lib/bcms_webdav/resource.rb

Overview

A virtual resource representing a CMS

* Section
* File
* Image

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.normalize_path(webdav_path) ⇒ Object

Converts WebDAV paths into CMS paths. Both have slightly different rules.



13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/bcms_webdav/resource.rb', line 13

def self.normalize_path(webdav_path)
  path = webdav_path
  if path.end_with?("/")
    path.gsub!(/\/$/, '')
  end
  unless path.start_with?("/")
    path = path.insert(0, "/")
  end
  path = "/" if path == ''
  path

end

Instance Method Details

#authenticate(username, password) ⇒ Object



27
28
29
30
31
32
33
34
35
36
# File 'lib/bcms_webdav/resource.rb', line 27

def authenticate(username, password)
  log "Authenticating user '#{username}'"
  user = Cms::User.authenticate(username, password)

  unless user
    Rails.logger.error "Failed authentication attempt by user '#{username}'"
    return false
  end
  user.able_to?(:administrate)
end

#childrenObject



84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/bcms_webdav/resource.rb', line 84

def children
  if exist?
    child_nodes = @section.child_nodes
    child_resources = []
    child_nodes.each do |node|
      child_resources << child_node(node)
    end
    child_resources.compact!
    return child_resources
  else
    []
  end
end

#collection?Boolean

Returns:

  • (Boolean)


108
109
110
# File 'lib/bcms_webdav/resource.rb', line 108

def collection?
  have_section ? true : false
end

#content_lengthObject



120
121
122
# File 'lib/bcms_webdav/resource.rb', line 120

def content_length
  have_file ? @resource.size : 0
end

#content_typeObject



116
117
118
# File 'lib/bcms_webdav/resource.rb', line 116

def content_type
  have_file ? @resource.file_type : "text/html"
end

#creation_dateObject

1 year ago handles missing files (which is hopefully a temporary bug while trying to upgrade to CMS 3.5)



99
100
101
# File 'lib/bcms_webdav/resource.rb', line 99

def creation_date
  @resource ? @resource.created_at : 1.year.ago
end

#etagObject



112
113
114
# File 'lib/bcms_webdav/resource.rb', line 112

def etag
  sprintf('%x-%x-%x', @resource.id, creation_date.to_i, last_modified.to_i) if exist?
end

#exist?Boolean

This should always be called by DAV4Rack controller before any other primary operation (get, put) on a resource.

Returns:

  • (Boolean)


53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/bcms_webdav/resource.rb', line 53

def exist?
  path_to_find = Resource.normalize_path(path)
  @section = Cms::Section.with_path(path_to_find).first

  if have_section
    log_exists('section', path_to_find)
    @resource = @section if have_section
  end

  @page = Cms::Page.with_path(path_to_find).first
  if have_page
    log_exists('page', path_to_find)
    @resource = @page
  end

  @file = Cms::Attachment.find_live_by_file_path(path)
  if have_file
    log_exists('file', path_to_find)
    @resource = @file
  end

  have_section || have_page || have_file
end

#find_section_for(path) ⇒ Object



178
179
180
181
182
183
# File 'lib/bcms_webdav/resource.rb', line 178

def find_section_for(path)
  path_obj = Path.new(path)
  section_path = path_obj.path_without_filename
  path_to_find = Resource.normalize_path(section_path)
  Cms::Section.with_path(path_to_find).first
end

#get(request, response) ⇒ Object



124
125
126
127
128
129
130
131
132
133
# File 'lib/bcms_webdav/resource.rb', line 124

def get(request, response)
  # log "GET request for #{request.path}"
  if have_file
    path_to_file = @resource.data.path
    # log "For attachment '#{@resource}' path to file is '#{path_to_file}"
    file = Bcms::WebDAV::File.new(path_to_file)
    log "Sending file '#{path_to_file}'"
    response.body = file
  end
end

#have_fileObject



46
47
48
# File 'lib/bcms_webdav/resource.rb', line 46

def have_file
  @file != nil
end

#have_pageObject



42
43
44
# File 'lib/bcms_webdav/resource.rb', line 42

def have_page
  @page != nil
end

#have_sectionObject



38
39
40
# File 'lib/bcms_webdav/resource.rb', line 38

def have_section
  @section != nil
end

#last_modifiedObject



103
104
105
106
# File 'lib/bcms_webdav/resource.rb', line 103

def last_modified
  return @resource.created_at if exist?
  1.year.ago
end

#parentObject

Find the parent resource. We cache the result here so it can be loaded from the DB properly.



78
79
80
81
82
# File 'lib/bcms_webdav/resource.rb', line 78

def parent
  return @parent if @parent
  @parent = super
  @parent
end

#public_pathObject

Ensures path is encoded. In most cases, an encoded path may occur after uploading a file (PUT) with special characters in it.



161
162
163
164
165
166
167
168
169
# File 'lib/bcms_webdav/resource.rb', line 161

def public_path
  p = super
  begin
    URI(p)
  rescue URI::InvalidURIError
    return URI.escape(p)
  end
  p
end

#put(request, response) ⇒ Object

Handle uploading file.



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/bcms_webdav/resource.rb', line 136

def put(request, response)
  temp_file = extract_tempfile(request)
  section = find_section_for(path)

  file_block = Cms::FileBlock.new(:name=>path, :publish_on_save=>true)
  file_block.attachments.build(:data => temp_file, :attachment_name => 'file', :parent => section, :data_file_path => path)
  
  # Ensure the file pointer is at the beginning so Paperclip can copy after the block is saved.
  # Something in assigning the tempfile to the Block is not correctly rewinding the file.
  # Not doing this causes an empty file to be saved in uploads directory.
  temp_file.rewind
  
  unless file_block.save
    log "Couldn't save file."
    file_block.errors.each do |error|
      log error
    end
    work_around_dav4rack_bug
    return InternalServerError
  end
  Created
end

#work_around_dav4rack_bugObject

If Created isn’t returned, dav4rack controller will set the body to nil, which will cause Rack to blow up. i.e. response.body = response but ‘Location’ is only set if Created == true See github.com/chrisroberts/dav4rack/blob/master/lib/dav4rack/controller.rb#put



174
175
176
# File 'lib/bcms_webdav/resource.rb', line 174

def work_around_dav4rack_bug
  response['Location'] = ''
end