Protect uploads with a password
[coquelicot.git] / coquelicot.rb
1 require 'sinatra'
2 require 'haml'
3 require 'digest/sha1'
4 require 'singleton'
5
6 enable :inline_templates
7
8 set :upload_password, '0e5f7d398e6f9cd1f6bac5cc823e363aec636495'
9
10 def password_match?(password)
11   return TRUE if settings.upload_password.nil?
12   (not password.nil?) && Digest::SHA1.hexdigest(password) == settings.upload_password
13 end
14
15 def uploaded_file(file)
16   "#{options.root}/files/#{file}"
17 end
18
19 get '/style.css' do
20   content_type 'text/css', :charset => 'utf-8'
21   sass :style
22 end
23
24 get '/' do
25   haml :index
26 end
27
28 get '/ready/:name' do |name|
29   path = uploaded_file(name)
30   unless File.exists? path then
31     return 404
32   end
33   base = request.url.gsub(/\/ready\/[^\/]*$/, '')
34   @url = "#{base}/#{name}"
35   haml :ready
36 end
37
38 get '/:name' do |name|
39   path = uploaded_file(name)
40   unless File.exists? path then
41     return 404
42   end
43   send_file path
44 end
45
46 post '/upload' do
47   unless password_match? params[:upload_password] then
48     return 403
49   end
50   if params[:file] then
51     tmpfile = params[:file][:tempfile]
52     name = params[:file][:filename]
53   end
54   if tmpfile.nil? || name.nil? then
55     @error = "No file selected"
56     return haml(:index)
57   end
58   FileUtils::cp(tmpfile.path, uploaded_file(name))
59   redirect "ready/#{name}"
60 end
61
62 helpers do
63   def base_href
64     url = request.scheme + "://"
65     url << request.host
66     if request.scheme == "https" && request.port != 443 ||
67         request.scheme == "http" && request.port != 80
68       url << ":#{request.port}"
69     end
70     url << request.script_name
71     "#{url}/"
72   end
73 end
74
75 __END__
76
77 @@ layout
78 %html
79   %head
80     %title coquelicot
81     %base{ :href => base_href }
82     %link{ :rel => 'stylesheet', :href => "style.css", :type => 'text/css',
83            :media => "screen, projection" }
84     %script{ :type => 'text/javascript', :src => 'javascripts/jquery.min.js' }
85     %script{ :type => 'text/javascript', :src => 'javascripts/jquery.lightBoxFu.js' }
86     %script{ :type => 'text/javascript', :src => 'javascripts/jquery.uploadProgress.js' }
87     %script{ :type => 'text/javascript', :src => 'javascripts/coquelicot.js' }
88   %body
89     #container
90       = yield
91
92 @@ index
93 %h1 Upload!
94 - unless @error.nil?
95   .error= @error
96 %form#upload{ :enctype => 'multipart/form-data',
97               :action  => 'upload', :method => 'post' }
98   .field
99     %input{ :type => 'file', :name => 'file' }
100   .field
101     %input{ :type => 'submit', :value => 'Send file' }
102
103 @@ ready
104 %h1 Pass this on!
105 .url
106   %a{ :href => @url }= @url
107
108 @@ style
109 $green: #00ff26
110
111 body
112   background-color: $green
113   font-family: Georgia
114   color: darkgreen
115
116 a, a:visited
117   text-decoration: underline
118   color: white
119
120 .error
121   background-color: red
122   color: white
123   border: black solid 1px
124
125 #progress
126   margin: 8px
127   width: 220px
128   height: 19px
129
130 #progressbar
131   background: url('images/ajax-loader.gif') no-repeat
132   width: 0px
133   height: 19px