www/roster/views/actions/memstat.json.rb (178 lines of code) (raw):

# get entry for @userid require 'wunderbar' user = ASF::Person.find(@userid) entry = user.members_txt(true) raise Exception.new("Unable to find member entry for #{@userid}") unless entry USERID = user.id USERMAIL = "#{USERID}@apache.org" USERNAME = user.cn TIMESTAMP = (Time.now.strftime '%Y-%m-%d %H:%M:%S %:z') # identify file to be updated members_txt = ASF::SVN.svnpath!('foundation', 'members.txt') # construct commit message message = "Action #{@action} for #{USERID}" if @action == 'involuntary_emeritus' if @emeritus_reason.size < 10 raise Exception.new("Missing or incomplete reason provided: '#{@emeritus_reason}'") end message = "Action #{@action} for #{USERID}: #{@emeritus_reason}" end # update members.txt only for secretary actions if %w{active emeritus deceased involuntary_emeritus}.include? @action ASF::SVN.multiUpdate_ members_txt, message, env, _ do |text| # remove user's entry unless text.sub! entry, '' # e.g. if the workspace was out of date raise Exception.new('Failed to remove existing entry -- try refreshing') end extra = [] # determine where to put the entry if @action == 'emeritus' # move to emeritus index = text.index(/^\s\*\)\s/, text.index(/^Emeritus/)) entry.sub! %r{\s*/\* deceased, .+?\*/},'' # drop the deceased comment if necessary # if pending emeritus request was found, move it to emeritus pathname, basename = ASF::EmeritusRequestFiles.findpath(user) if pathname # Add details of emeritus file commit. # The file is moved to the emeritus directory as part of the commit, so we show today's date # and the details of the file from the received directory. info = ASF::SVN.getInfoAsHash(pathname, env.user, env.password) reason = "updated #{Time.now.utc.strftime "%Y-%m-%d"} received as r#{info['Last Changed Rev']} #{info['Last Changed Date'].split().first}}" entry.sub! "\n", " /* emeritus, #{reason} */\n" # add the reason comment extra << ['mv', pathname, ASF::SVN.svnpath!('emeritus', basename)] else # there should be a request file _warn 'Emeritus request file not found' end elsif @action == 'involuntary_emeritus' # move to emeritus index = text.index(/^\s\*\)\s/, text.index(/^Emeritus/)) entry.sub! %r{\s*/\* deceased, .+?\*/},'' # drop the deceased comment if necessary entry.sub! "\n", " /* involuntary, #{@emeritus_reason} */\n" # add the reason comment elsif @action == 'active' # revert to active index = text.index(/^\s\*\)\s/, text.index(/^Active/)) entry.sub! %r{\s*/\* (?:deceased|involuntary|emeritus), .+?\*/},'' # drop the comments if necessary # if emeritus file was found, move it to emeritus-reinstated # otherwise ignore pathname, basename = ASF::EmeritusFiles.findpath(user) if pathname # TODO: allow for previous reinstated file extra << ['mv', pathname, ASF::SVN.svnpath!('emeritus-reinstated', basename)] end elsif @action == 'deceased' index = text.index(/^\s\*\)\s/, text.index(/^Deceased/)) entry.sub! "\n", " /* deceased, #{@dod} */\n" # add the deceased comment end # perform the insertion text.insert index, entry # return the updated (and normalized) text and extra svn command [ASF::Member.normalize(text), extra] end elsif @action == 'withdraw' # process withdrawal request (secretary only) require 'whimsy/asf/subreq' # TODO # Check members.md for entry and report - how? # unsubscribe from member only mailing lists: all_mail = user.all_mail # their known emails pmc_chair = ASF.pmc_chairs.include?(user) # to which (P)PMCs do they belong? ldap_pmcs = user.committees.map(&:mail_list) ldap_pmcs += user.podlings.map(&:mail_list) # What are their subscriptions? subs = ASF::MLIST.subscriptions(all_mail)[:subscriptions] subs += ASF::MLIST.digests(all_mail)[:digests] # Check subscriptions for readability subs.each do |list, email| unless ASF::Mail.canread(list, false, pmc_chair, ldap_pmcs) request = ASF::Subreq.create_request(user, email, list) ASF::Subreq.queue_request('unsub', request, nil, {env: env}) end end # remove from LDAP member group ASF::LDAP.bind(env.user, env.password) do ASF::Group['member'].remove(user) end # Remove from members.txt Tempfile.create('withdraw') do |tempfile| ASF::SVN.multiUpdate_ members_txt, message, env, _, {verbose: true} do |text| extra = [] # remove user's entry unless text.sub! entry, '' # e.g. if the workspace was out of date raise Exception.new('Failed to remove existing entry -- try refreshing') end # save the entry to the archive File.write(tempfile, entry) tempfile.close extra << ['put' , tempfile.path, ASF::SVN.svnpath!('withdrawn', 'archive', "#{@userid}.txt")] # Find matching request for the id pathname, basename = ASF::WithdrawalRequestFiles.findpath(@userid, env) unless pathname raise Exception.new("Failed to find withdrawal pending file for #{@userid}") end # Move the request from pending - this should also work for directories extra << ['mv', pathname, ASF::SVN.svnpath!('withdrawn', basename)] [ASF::Member.normalize(text), extra] end ASF::WithdrawalRequestFiles.refreshnames(true, env) # update the listing if successful # Send confirmation email ASF::Mail.configure mail = Mail.new do from 'secretary@apache.org' to "#{USERNAME}<#{USERMAIL}>" subject "Acknowledgement of membership withdrawal from #{USERNAME}" text_part do body <<~EOD The membership withdrawal request that was registered for you has now been actioned. Your details have been removed from the membership roster. You have also been unsubscribed from members-only private email lists. Warm Regards, Secretary, Apache Software Foundation secretary@apache.org EOD end end mail.deliver! end elsif @action == 'rescind_withdrawal' # Secretary only pathname, _basename = ASF::WithdrawalRequestFiles.findpath(@userid, env) if pathname ASF::SVN.svn_!('rm', pathname, _, {env:env, msg:message}) ASF::WithdrawalRequestFiles.refreshnames(true, env) # update the listing ASF::Mail.configure mail = Mail.new do from 'secretary@apache.org' to "#{USERNAME}<#{USERMAIL}>" subject "Acknowledgement of withdrawal rescindment from #{USERNAME}" text_part do body <<~EOD This acknowledges receipt of your request to rescind your membership withdrawal request. The request has been deleted, and your membership status will be unaffected. Warm Regards, Secretary, Apache Software Foundation secretary@apache.org EOD end end mail.deliver! else _warn "Withdrawal request file not found for #{@userid}" end end # Owner operations if @action == 'rescind_emeritus' # TODO handle case where rescinded file already exists pathname, basename = ASF::EmeritusRequestFiles.findpath(user) if pathname ASF::SVN.svn_!('mv', [pathname, ASF::SVN.svnpath!('emeritus-requests-rescinded', basename)], _, {env:env, msg:message}) else _warn 'Emeritus request file not found' end elsif @action == 'request_emeritus' # Create emeritus request and send acknowledgement mail from secretary # TODO URL should be a config constant ... code, template = ASF::Git.github('apache/www-site/main/content/forms/emeritus-request.txt') raise 'Failed to read emeritus-request.txt: ' + code unless code == '200' centered_id = USERID.center(55, '_') centered_name = USERNAME.center(55, '_') centered_date = TIMESTAMP.center(25, '_') signed_request = template .sub(/Apache id: _+/, ('Apache id: ' + centered_id)) .sub(/Full name: _+/, ('Full name: ' + centered_name)) .sub(/Signed: _+/, 'Signed by validated user at: ________Whimsy www/committer_________') .sub(/Date: _+/, ('Date: ' + centered_date)) # Write the emeritus request to emeritus-requests-received EMERITUS_REQUEST_URL = ASF::SVN.svnpath!('emeritus-requests-received') rc = ASF::SVN.create_(EMERITUS_REQUEST_URL, "#{USERID}.txt", signed_request, "Emeritus request from #{USERNAME} (#{USERID})", env, _) if rc == 0 ASF::Mail.configure mail = Mail.new do from 'secretary@apache.org' to "#{USERNAME}<#{USERMAIL}>" subject "Acknowledgement of emeritus request from #{USERNAME}" text_part do body "This acknowledges receipt of your emeritus request. You can find the request at #{EMERITUS_REQUEST_URL}#{USERID}.txt. A copy is attached for your records.\n\nWarm Regards,\n\nSecretary, Apache Software Foundation\nsecretary@apache.org\n\n" end end mail.attachments["#{USERID}.txt"] = signed_request mail.deliver! elsif rc == 1 _warn 'Request file already exists' end elsif @action == 'request_reinstatement' ASF::Mail.configure mail = Mail.new do to 'secretary@apache.org' cc "#{USERNAME}<#{USERMAIL}>" from USERMAIL subject "Emeritus reinstatement request from #{USERNAME}" text_part do body "I respectfully request reinstatement to full membership in The Apache Software Foundation.\n\nRegards,\n\n#{USERNAME}" end end mail.deliver! end # return updated committer info _committer Committer.serialize(@userid, env)