You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@whimsical.apache.org by Sam Ruby <ru...@apache.org> on 2015/12/29 16:00:03 UTC
[whimsy.git] [1/1] Commit d104dd6: rough in server side of icla processing
Commit d104dd6dfb7dac0f629a7ee6400ce6ec1b5b6415:
rough in server side of icla processing
Branch: refs/heads/secmail
Author: Sam Ruby <ru...@intertwingly.net>
Committer: Sam Ruby <ru...@intertwingly.net>
Pusher: rubys <ru...@apache.org>
------------------------------------------------------------
www/secmail/README | + -
www/secmail/helpers.rb | +++++++++++
www/secmail/models/attachment.rb | ++++++++++++++
www/secmail/models/mailbox.rb | ++++++++
www/secmail/models/message.rb | +++++++++++++++
www/secmail/server.rb | +
www/secmail/views/actions/burst.json.rb | + ----
www/secmail/views/actions/check-signature.json.rb | + ----
www/secmail/views/actions/delete-attachment.json.rb | + ----
www/secmail/views/actions/drop.json.rb | + ----
www/secmail/views/actions/icla.json.rb | +++++++++++++
www/secmail/views/actions/rotate-attachment.json.rb | + ----
www/secmail/views/forms/icla.js.rb | + -
www/secmail/views/parts.js.rb | ++++++ ---
------------------------------------------------------------
148 changes: 121 additions, 27 deletions.
------------------------------------------------------------
diff --git a/www/secmail/README b/www/secmail/README
index 161a350..14ec74e 100644
--- a/www/secmail/README
+++ b/www/secmail/README
@@ -18,7 +18,7 @@ Notes:
Secretary email archive currently requires about approximately 11 Gigabytes.
- Some functions will require installations of imageMagick and pdftk.
+ Some functions will require installations of gpg, imageMagick and pdftk.
OS X El Capitan users may want to look at:
http://stackoverflow.com/a/33248310
diff --git a/www/secmail/helpers.rb b/www/secmail/helpers.rb
new file mode 100644
index 0000000..9987346
--- /dev/null
+++ b/www/secmail/helpers.rb
@@ -0,0 +1,11 @@
+helpers do
+ # update and restore an svn checkout to a clean state
+ def svn_reset(repos)
+ path = File.realpath(repos).untaint
+ out, err, rc = Open3.capture3 'svn', 'cleanup', path
+ out, err, rc = Open3.capture3 'svn', 'revert', '--recursive', path
+ out, err, rc = Open3.capture3 'svn', 'status', path
+ File.unlink *out.scan(/^\?\s+(.*)/).flatten.map(&:untaint)
+ out, err, rc = Open3.capture3 'svn', 'update', path
+ end
+end
diff --git a/www/secmail/models/attachment.rb b/www/secmail/models/attachment.rb
index 4035515..d2fbd83 100644
--- a/www/secmail/models/attachment.rb
+++ b/www/secmail/models/attachment.rb
@@ -53,4 +53,31 @@ def as_pdf
return file
end
+
+ # write a file out to svn
+ def write_svn(repos, file)
+ if file.start_with? '.' or file !~ /\A[-.\w]+\Z/
+ raise IOError.new("Invalid filename: #{file}")
+ end
+
+ filename = File.join(repos, file)
+
+ if Dir.exist? filename
+ if name.start_with? '.' or name !~ /\A[.\w]+\Z/
+ raise IOError.new("Invalid filename: #{name}")
+ end
+
+ filename = File.join(filename, name)
+ raise Errno::EEXIST.new(File.join(file, name)) if File.exist? filename
+ else
+ raise Errno::EEXIST.new(file) if File.exist? filename
+ end
+
+ File.write filename, body, encoding: Encoding::BINARY
+
+ system 'svn', 'add', filename
+ system 'svn', 'propset', 'svn:mime-type', content_type.untaint, filename
+
+ filename
+ end
end
diff --git a/www/secmail/models/mailbox.rb b/www/secmail/models/mailbox.rb
index 197c32e..f945a59 100644
--- a/www/secmail/models/mailbox.rb
+++ b/www/secmail/models/mailbox.rb
@@ -107,6 +107,14 @@ def messages
#
# Find a message
#
+ def self.find(message)
+ month, hash = message.match(%r{/(\d+)/(\w+)}).captures
+ Mailbox.new(month).find(hash)
+ end
+
+ #
+ # Find a message
+ #
def find(hash)
headers = YAML.load_file(yaml_file) rescue {}
email = messages.find {|message| Mailbox.hash(message) == hash}
diff --git a/www/secmail/models/message.rb b/www/secmail/models/message.rb
index 0beab95..aa4ab4c 100644
--- a/www/secmail/models/message.rb
+++ b/www/secmail/models/message.rb
@@ -86,4 +86,34 @@ def write
yaml[@hash] = @headers
end
end
+
+ # write one or more attachments to directory containing an svn checkout
+ def write_svn(repos, filename, *attachments)
+ attachments = attachments.flatten.compact
+
+ if attachments.length == 1
+ ext = File.extname(attachments.first).untaint
+ find(attachments.first).write_svn(repos, filename + ext)
+ else
+ # validate filename
+ if filename.start_with? '.' or filename !~ /\A[.\w]\Z/
+ raise IOError.new("invalid filename: #{filename}")
+ end
+
+ # ensure directory doesn't exist
+ dest = File.join(iclas, filename).untaint
+ raise Errno::EEXIST.new(filename) if File.exist? dest
+
+ # create directory
+ Dir.mkdir dest
+ Kernel.system 'svn', 'add', dest
+
+ # write out selected attachment
+ attachments.each do |attachment|
+ find(attachment).write_svn(repos, dest)
+ end
+
+ File.join(repos, dest)
+ end
+ end
end
diff --git a/www/secmail/server.rb b/www/secmail/server.rb
index 74e170d..9a0c096 100644
--- a/www/secmail/server.rb
+++ b/www/secmail/server.rb
@@ -9,6 +9,7 @@
require 'ruby2js/filter/require'
require 'sanitize'
+require_relative 'helpers'
require_relative 'models/mailbox'
# list of messages
diff --git a/www/secmail/views/actions/burst.json.rb b/www/secmail/views/actions/burst.json.rb
index 83933f1..802adeb 100644
--- a/www/secmail/views/actions/burst.json.rb
+++ b/www/secmail/views/actions/burst.json.rb
@@ -2,10 +2,7 @@
# burst a document into separate pages
#
-month, hash = @message.match(%r{/(\d+)/(\w+)}).captures
-
-mbox = Mailbox.new(month)
-message = mbox.find(hash)
+message = Mailbox.find(@message)
attachments = []
diff --git a/www/secmail/views/actions/check-signature.json.rb b/www/secmail/views/actions/check-signature.json.rb
index 1565119..ab96bd5 100644
--- a/www/secmail/views/actions/check-signature.json.rb
+++ b/www/secmail/views/actions/check-signature.json.rb
@@ -2,10 +2,7 @@
# check signature on an attachment
#
-month, hash = @message.match(%r{/(\d+)/(\w+)}).captures
-
-mbox = Mailbox.new(month)
-message = mbox.find(hash)
+message = Mailbox.find(@message)
begin
# fetch attachment and signature
diff --git a/www/secmail/views/actions/delete-attachment.json.rb b/www/secmail/views/actions/delete-attachment.json.rb
index 9c6b578..07f1abf 100644
--- a/www/secmail/views/actions/delete-attachment.json.rb
+++ b/www/secmail/views/actions/delete-attachment.json.rb
@@ -2,10 +2,7 @@
# delete an attachment
#
-month, hash = @message.match(%r{/(\d+)/(\w+)}).captures
-
-mbox = Mailbox.new(month)
-message = mbox.find(hash)
+message = Mailbox.find(@message)
message.delete_attachment @selected
diff --git a/www/secmail/views/actions/drop.json.rb b/www/secmail/views/actions/drop.json.rb
index 62c0308..830ce73 100644
--- a/www/secmail/views/actions/drop.json.rb
+++ b/www/secmail/views/actions/drop.json.rb
@@ -2,10 +2,7 @@
# drop part of drag and drop
#
-month, hash = @message.match(%r{/(\d+)/(\w+)}).captures
-
-mbox = Mailbox.new(month)
-message = mbox.find(hash)
+message = Mailbox.find(@message)
begin
source = message.find(@source).as_pdf
diff --git a/www/secmail/views/actions/icla.json.rb b/www/secmail/views/actions/icla.json.rb
index 520a360..35f7fbc 100644
--- a/www/secmail/views/actions/icla.json.rb
+++ b/www/secmail/views/actions/icla.json.rb
@@ -1 +1,26 @@
+#
+# File an ICLA
+#
+
+message = Mailbox.find(@message)
+iclas = ASF::SVN['private/documents/iclas']
+
+# write attachment (+ signature, if present) to the documents/iclas directory
+svn_reset iclas
+dest = message.write_svn(iclas, @filename, @selected, @signature)
+
+# construct line to be inserted
+insert = [
+ 'notinavail',
+ @realname.strip,
+ @pubname.strip,
+ @email.strip,
+ "Signed CLA; #{@filename}"
+].join(':')
+
+# update iclas.txt
+svn_reset ASF::ICLA::OFFICERS
+iclas_txt = ASF::ICLA.sort(File.read(ASF::ICLA::SOURCE) + insert + "\n")
+File.write ASF::ICLA::SOURCE, iclas_txt
+
{result: "stub for ICLA, filename: #{@filename}"}
diff --git a/www/secmail/views/actions/rotate-attachment.json.rb b/www/secmail/views/actions/rotate-attachment.json.rb
index 3e0244e..d61000b 100644
--- a/www/secmail/views/actions/rotate-attachment.json.rb
+++ b/www/secmail/views/actions/rotate-attachment.json.rb
@@ -2,10 +2,7 @@
# drop part of drag and drop
#
-month, hash = @message.match(%r{/(\d+)/(\w+)}).captures
-
-mbox = Mailbox.new(month)
-message = mbox.find(hash)
+message = Mailbox.find(@message)
begin
selected = message.find(@selected).as_pdf
diff --git a/www/secmail/views/forms/icla.js.rb b/www/secmail/views/forms/icla.js.rb
index 004b36f..d96c41e 100644
--- a/www/secmail/views/forms/icla.js.rb
+++ b/www/secmail/views/forms/icla.js.rb
@@ -104,7 +104,7 @@ def componentDidUpdate()
# generate file name from the public name
def genfilename()
- @filename ||= @pubname.downcase().gsub(/\W/, '-') + '.pdf'
+ @filename ||= @pubname.downcase().gsub(/\W/, '-')
end
# show new account request window with fields filled in
diff --git a/www/secmail/views/parts.js.rb b/www/secmail/views/parts.js.rb
index c371f20..a78c894 100644
--- a/www/secmail/views/parts.js.rb
+++ b/www/secmail/views/parts.js.rb
@@ -37,9 +37,7 @@ def render
options[:className] = 'dragging'
elsif attachment == @selected
options[:className] = 'selected'
- elsif attachment == @selected + '.asc'
- options[:className] = 'signature'
- elsif attachment == @selected + '.sig'
+ elsif attachment == @selected + '.asc' or attachment == @selected + '.sig'
options[:className] = 'signature'
else
options[:className] = nil
@@ -251,13 +249,22 @@ def submit(event)
event.preventDefault()
form = event.currentTarget
- data = {}
+ # collect up name of selected attachment and all input fields
+ data = {message: window.parent.location.pathname, selected: @selected}
Array(form.querySelectorAll('input')).each do |field|
data[field.name] = field.value if field.name
end
+ # add signature (if present)
+ @attachments.each do |attachment|
+ if attachment == @selected + '.asc' or attachment == @selected + '.sig'
+ data.signature = attach
+ end
+ end
+
+ # submit HTTP post request
@busy = true
- HTTP(post form.action, data).then {|response|
+ HTTP.post(form.action, data).then {|response|
@busy = false
alert response.result
}.catch {|error|