aperture/src/aperture.rb
snow flurry f25803aaa5 multiple syntax fixes
I never said I was *good* at ruby...
2021-03-24 21:47:17 -07:00

126 lines
3.3 KiB
Ruby

#!/usr/bin/env ruby
## TODO: Can we somehow make this dynamic?
CONF_PATH = "/etc/aperture.conf"
USER_PREFIX = "~"
require 'cgi'
require 'yaml'
require_relative 'libmagic'
$cgi = CGI.new
# convenience function to print an error to CGI log and quit
def die(status, error)
$cgi.print $cgi.http_header(
"type" => "text/plain",
"status" => status
)
if status == "SERVER_ERROR"
$stderr.puts "[aperture:fatal] " + error
$cgi.print "Something went wrong! Ask the server admin to check the logs for more info."
else
$cgi.print error
end
exit
end
def get_yaml(path)
if not File.file? path
die("SERVER_ERROR", "Application not configured")
end
begin
cfg = YAML.load(
File.open(path).read
)
return cfg
rescue
die("SERVER_ERROR", "Config file broken ;_;")
end
# should be unreachable
die("SERVER_ERROR", "get_yaml broken ;_;")
end
# sanitizes string so all that's left is alphanumerics and .
def sanitize(str)
return str.gsub(/(^\.|[^0-9a-zA-Z\.])/i, '_')
end
# main function
def main()
# consistency checks for request
# if not authenticated, ignore
if $cgi.remote_user.nil? || $cgi.remote_user.empty?
die("FORBIDDEN", "")
end
# even though remote_user comes from the upstream, don't trust it
clean_name = sanitize $cgi.remote_user
# Only POST supported for this API
if $cgi.request_method != "POST"
die("METHOD_NOT_ALLOWED", "Method not allowed")
end
if !$cgi.content_type.start_with?("multipart/form-data")
die("NOT_ACCEPTABLE", "Please use multipart/form-data, you're using " + $cgi.content_type)
end
cfg = get_yaml CONF_PATH
# make sure expected config entries are there
if cfg['save_path'].nil? or cfg['save_path'].empty?
die "SERVER_ERROR", "config: save_path not set!"
end
if cfg['root_url'].nil? or cfg['root_url'].empty?
die "SERVER_ERROR", "config: root_url not set!"
end
# XXX: configurable prefix?
user_dir = cfg['save_path'] + "/" + USER_PREFIX + clean_name
if not File.directory? user_dir
die("SERVER_ERROR", "User directory " + user_dir + " doesn't exist!")
end
# get file data
if $cgi.params['sendfile'].nil? || $cgi.params['sendfile'].empty?
die("NOT_ACCEPTABLE", "Missing sendfile?")
end
upfile = $cgi.params['sendfile'][0]
# get the mime type from the file contents, not HTTP
lm = LibMagic::Magic.new(cfg['magic_path'])
ftype = lm.get_mime_type(upfile)
if ftype.match(/^(image|text|audio|video)\/[a-zA-Z0-9\-\.]+$/).nil?
die("NOT_ACCEPTABLE", "MIME type " + ftype + " not supported here")
end
lm.close
clean_file = sanitize upfile.original_filename
full_path = user_dir + "/" + clean_file
# don't overwrite an existing file unless they asked for it
if $cgi.params['overwrite'] != "true" and File.exists? full_path
die("NOT_ACCEPTABLE" "File " + clean_file + " already exists!")
end
# finally, store the file
File.open(full_path, "w") do |new_file|
new_file.write(upfile.read)
end
# print OK and send URL
$cgi.print $cgi.http_header("status" => "OK",
"type" => "text/plain")
$cgi.print cfg['root_url'] + USER_PREFIX + clean_name + "/" + clean_file
end
main
exit 0