| # |
| # File an membership application: |
| # - add files to documents/member_apps |
| # - add entry to foundation/members.txt |
| # - update memapp-received.txt |
| # - respond to original email |
| # |
| |
| # extract message |
| message = Mailbox.find(@message) |
| |
| # extract file extension |
| fileext = File.extname(@selected).downcase if @signature.empty? |
| |
| # verify that a membership form under that name stem doesn't already exist |
| if "#@filename#{fileext}" =~ /\A\w[-\w]*\.?\w*\z/ # check taint requirements |
| # returns name if it matches as stem or fully (e.g. for directory) |
| form = ASF::MemApps.search @filename.untaint |
| if form |
| _warn "documents/member_apps/#{form} already exists" |
| end |
| else |
| _warn "Invalid filename or extension" |
| end |
| |
| # obtain per-user information |
| _personalize_email(env.user) |
| |
| # initialize commit message |
| @document = "Membership Application for #{@fullname}" |
| |
| ######################################################################## |
| # document/member_apps # |
| # members.txt # |
| ######################################################################## |
| |
| # write attachment (+ signature, if present) to the documents/member_apps |
| # directory |
| task "svn commit documents/member_apps/#@filename#{fileext} and update members.txt" do |
| # Construct initial entry: |
| fields = { |
| fullname: @fullname, |
| address: @addr, |
| country: @country, |
| email: @email, |
| tele: @tele, |
| fax: @fax, |
| availid: @availid, |
| } |
| @entry = ASF::Member.make_entry(fields) |
| |
| form do |
| _input value: @selected, name: 'selected' |
| |
| if @signature and not @signature.empty? |
| _input value: @signature, name: 'signature' |
| end |
| |
| _textarea @entry, name: 'entry', rows: @entry.split("\n").length |
| end |
| |
| complete do |dir| |
| |
| svn_multi('foundation', 'members.txt', 'member_apps', @selected, @signature, @filename, fileext, message, @document) do |members_txt| |
| |
| # update members.txt |
| # TODO this should be a library method |
| pattern = /^Active.*?^=+\n+(.*?)^Emeritus/m |
| data = members_txt.scan(pattern).flatten.first |
| members = data.split(/^\s+\*\)\s+/) |
| members.shift |
| members.push @entry |
| members_txt[pattern,1] = " *) " + members.join("\n *) ") |
| members_txt[/We now number (\d+) active members\./,1] = members.length.to_s |
| ASF::Member.sort(members_txt) |
| end |
| |
| end |
| end |
| |
| ######################################################################## |
| # update cn=member,ou=groups,dc=apache,dc=org # |
| ######################################################################## |
| |
| task "update cn=member,ou=groups,dc=apache,dc=org in LDAP" do |
| form do |
| _input value: @availid, name: 'availid' |
| end |
| |
| complete do |
| ldap = ASF.init_ldap(true) |
| if ASF.memberids.include? @availid |
| _transcript ["#@availid already in group member"] |
| else |
| ldap.bind("uid=#{env.user.untaint},ou=people,dc=apache,dc=org", |
| env.password.untaint) |
| |
| ldap.modify "cn=member,ou=groups,dc=apache,dc=org", |
| [LDAP.mod(LDAP::LDAP_MOD_ADD, 'memberUid', [@availid])] |
| |
| log = ["LDAP mod add: #{ldap.err2string(ldap.err)} (#{ldap.err})"] |
| if ldap.err == 0 |
| _transcript log |
| else |
| _backtrace log |
| end |
| |
| ldap.unbind |
| end |
| end |
| end |
| |
| ######################################################################## |
| # subscribe to members@apache.org # |
| ######################################################################## |
| |
| task "subscribe to members@apache.org" do |
| user = ASF::Person.find(@availid) |
| vars = { |
| version: 3, # This must match committers/subscribe.cgi#FORMAT_NUMBER |
| availid: @availid, |
| addr: @email, |
| listkey: 'members', |
| member_p: true, |
| chair_p: ASF.pmc_chairs.include?(user), |
| } |
| @subreq = JSON.pretty_generate(vars) + "\n" |
| |
| form do |
| _textarea @subreq, name: 'subreq', rows: @subreq.split("\n").length |
| end |
| |
| complete do |dir| |
| # determine file name |
| fn = "#{@availid}-members-#{Time.now.strftime '%Y%m%d-%H%M%S-%L'}.json" |
| fn.untaint if @availid =~ /^\w[-.\w]+$/ |
| |
| rc = ASF::SVN.create_(ASF::SVN.svnurl!('subreq'), fn, @subreq, @document, env, _) |
| raise RuntimeError.new("exit code: #{rc}") if rc != 0 |
| end |
| end |
| |
| ######################################################################## |
| # update memapp-received.txt # |
| ######################################################################## |
| |
| # TODO combine with other SVN updates |
| |
| task "svn commit memapp-received.text" do |
| meetings = ASF::SVN['Meetings'] |
| file = Dir["#{meetings}/2*/memapp-received.txt"].sort.last.untaint |
| received = File.read(file) |
| if received =~ /^no\s+\w+\s+\w+\s+\w+\s+#{@availid}\s/ |
| received[/^(no )\s+\w+\s+\w+\s+\w+\s+#{@availid}\s/,1] = 'yes' |
| end |
| received[/(no )\s+\w+\s+\w+\s+#{@availid}\s/,1] = 'yes' |
| received[/(no )\s+\w+\s+#{@availid}\s/,1] = 'yes' |
| received[/(no )\s+#{@availid}\s/,1] = 'yes' |
| @line = received[/.*\s#{@availid}\s.*/] |
| |
| form do |
| _input value: @line, name: 'line' |
| end |
| |
| complete do |dir| |
| meeting = file.split('/')[-2] |
| path = ASF::SVN.svnpath!('Meetings', meeting,'memapp-received.txt') |
| rc = ASF::SVN.update(path, @document, env, _, {diff: true}) do |tmpdir, input| |
| input[/.*\s#{@availid}\s.*/] = @line |
| input |
| end |
| raise RuntimeError.new("exit code: #{rc}") if rc != 0 |
| end |
| end |
| |
| ######################################################################## |
| # email submitter # |
| ######################################################################## |
| |
| # send confirmation email |
| task "email #@email" do |
| # build mail from template |
| mail = message.reply( |
| subject: @document, |
| from: @from, |
| to: "#{@fullname.inspect} <#{@email}>", |
| cc: 'secretary@apache.org', |
| body: template('mem.erb') |
| ) |
| |
| # drop members@ from the replies |
| if mail.cc.include? 'members@apache.org' |
| mail.cc = mail['cc'].value.select {|name| name !~ /\bmembers@apache.org\b/} |
| end |
| |
| # echo email |
| form do |
| _message mail.to_s |
| end |
| |
| # deliver mail |
| complete do |
| mail.deliver! |
| end |
| end |