At the Perl Toolchain Summit 2019 in Marlow/Bisham, I added a feature to manage PAUSE permissions per distribution, which I hope makes it easier for you to grant permissions to other contributors.

This was the fifth year of my PAUSE hacking. I had spent first two years to port PAUSE web interface from mod_perl to Plack to get rid of deprecated tools, and another two years from Plack to Mojolicious for more structure and understandability. PAUSE on Mojolicious was deloyed into production at the 2018 summit (I'm sorry I couldn't report this last year). However, it was still checked out from my mojo_wip branch, and fell back to the old PAUSE on Plack from time to time, e.g. when something weird was found in my branch, or to use new maintenance tools my branch didn't have. One of my goals this year was to resolve this issue.

Another goal was to add a feature to manage permissions per distribution, which I had been wanting to add for years. Miyagawa-san had written a "comaint" script (App::PAUSE::Comaint) in 2013 for the same purpose, but of course it should be better for PAUSE itself to have it. This meant I needed to add at least six new pages and their tests, a new column to a table and a script to fill it, which might be a little too much for four days. So, as always, I prepared them in my local repository before the summit, hoping I could merge them with just a little fine-tuning at the venue.

Another, more ambitious goal was to add a new permission described in "the PAUSE Operating Model" published in October, 2017. I also started implementing this on top of the above, but I bumped into a few blocking issues and couldn't finish prototyping at home.

The first day at the summit started with a group discussion on PAUSE. After we talked about a few topics such as fixing case of module names in the indices and a new OAuth2 feature proposed by Lee Johnson, we moved on to the issues about the Operating Model. The "admin" permission described in the model was renamed to "permission manager" (or "p" for short) permission to avoid confusion with the PAUSE admins (those who have administrative privileges on the PAUSE itself), and to avoid conflict with a deprecated "m" (mailing list) permission. We also agreed to copy "p" permissions to new modules in a distribution uploaded by another contributor, so that people with "p" permission could keep their manager right for the distribution after the upload.

After the discussion, I asked Andreas König to merge my mojo_wip branch into his master. As PAUSE on Mojolicious was in a different directory (lib/pause_2017) from the one for PAUSE on Plack (lib/pause_1999), this merge should not cause any conflicts. GitHub also assured "[t]his branch ha[d] no conflicts with the base branch". Nevertheless, it didn't go as smoothly as we had expected, because both branches had changed PREREQ_PM section in Makefile.PL and manual git rebase messed it. We also encountered another issue because my master branch was way too old. In the end, we had to make a fresh checkout from Andreas' master. We still had two checkouts and two configurations so that we could use one for staging/testing, but anyway, now both were from the same origin.

Meanwhile, Slaven Reziç fixed a certification issue on pause.cpan.org (a less-known entrance to the PAUSE) by launching another Perlbal for it. Impressive.

We moved on to the new permission-per-distribution feature. This was not to introduce a new distribution-wide permission, but to find relevant indexed modules from a distribution name and apply the requested change to each of them. However, at this point PAUSE could only tell which package was taken from which distribution path (such as A/AU/AUTHOR/Distname-Version.tar.gz). As a starter, we added a new column to hold a distribution name (without directory, version and extension parts), and filled it using a one-off script. I also showed what the pages looked like and asked a few people for comments. General response was they seemed ok but a little more information would be nice (the first version only listed distribution names). I started cherry-picking what I did at home while adding a spoonful of sugar on them.



I continued cherry-picking on the day 2. While I was adding explanatory texts and links to the pages, I found that the div ids in the HTML version of the operating model document were based on an incremental counter and were not suitable for a canonical url fragment. I replaced them with headline-based ids.

I also silenced log outputs from PAUSE on Mojolicious while testing under Travis CI environments.



Next morning, I finished cherry-picking and asked Andreas to deploy. Neil Bowers tried the new feature and encountered a problem: an SQL statemnt that I added at the venue to show more information, turned out to be too slow under the production environment (though it was not so slow under my local environment). Slaven helped us a lot to analyze this issue. It was MySQL version that mattered. I proposed to revert the feature but we decided to hide it instead. I was almost certain how to work around the problem, but to make sure, I started creating another environment to reproduce it at hand.

Meanwhile, I followed the practice Ricardo Signes started this year and added labels to GitHub issues to help us find which should belong to which team. I found I still had about thirty issues to address.



Next day I got up a little earlier and tested the workaround under the new environment before breakfast. I also fixed my mistakes while cherry-picking, and a few security issues spotted by a Burp report from Lee. After we merged them, I made the permission-per-distribution feature visible again. I also made a change to grant primary (first-come) permissions to a special ADOPTME user when someone gave them up, to avoid undesired takeover.

I then got involved in an argument that basically claimed that Mojolicious was too unstable and PAUSE should not use it. Though this was not the first time for me, how nice it was to have at the last day of the summit after my three-year port was merged into master. I was sorry I forgot to urge the person to go to a smaller room, but anyway, I'd like to clarify a few points:

If you have something you'd like to add to the PAUSE web interface but you are not familiar with Mojolicious, I'll help you. Last year I ported a reCAPTCHA feature David Golden implemented for PAUSE on Plack into PAUSE on Mojolicious.

Certainly Mojolicious has changed its interfaces sometimes, especially for new features, and a change in Mojolicious 8 did affect some of our templates, but as PAUSE only uses basic features of Mojolicious (plus a few plugins), it's less likely for us to be affected so often, and it would not be so hard to fix if affected. I don't think we need to worry about hypothetical worst cases too much.

Not only PAUSE and a few other services I maintain, but several more toolchain applications (including MetaCPAN and CPAN Testers APIs) have already been using Mojolicious, at least for some part. The OAuth2 proposal was based on Mojolicious::Plugin::OAuth2::Server as well. It's probably easier to find a new contributor who knows Mojolicious than to find someone who knows an arbitrary set of alternative modules plus raw Plack.

According to two Burp reports from Lee, PAUSE on Mojolicious had fewer security issues than PAUSE on Plack, partly because Mojolicious is actively maintained and quicker to apply fixes and new Internet standards.

If you still consider it better not to use Mojolicious, you can restart from PAUSE on Plack, though I think it would be a huge waste of time and resources.



I went out for fresh air, wondering if I should spend the rest of the day doing something else, maybe for CPANTS and such, but it was a little too late. I took deep breaths, and went back to restart fixing smaller PAUSE issues. I made it possible to edit user information even when their email address was CENSORED, while I added an email address validation for a new user request. I also removed a note on direct upload from GitHub (that was more error prone anyway), and let PAUSE warn if unstable version was going to be reindexed.

Meanwhile, Ricardo Signes took care of my years-old pull requests for the PAUSE indexer that I should have added tests. This made me really happy. All's well that ends well.

Many thanks to Neil Bowers, Philippe Bruhat, and Laurent Boivin for organizing this event again, and to Wendy Van Dijk for food and kindness, and to our generous sponsors: Booking.com, cPanel, MaxMind, FastMail, ZipRecruiter, Cogendo, Elastic, OpenCage Data, Perl Services, Zoopla, Archer Education, OpusVL, Oetiker+Partner, SureVoIP, YEF.

