Super Pi Part 9: WebDAV
Just when I thought I was done adding things to Super Pi, I discovered another thing to add: a WebDAV server. I already have a Samba share, why do I need WebDAV? I've been looking at getting a Pine phone for at least 6 months now, and if I've learned anything about myself, it's that if I've been thinking about getting something that long, eventually it's going to happen. To make sure I would be able to handle not having an app store (or a more limited one), I took inventory of what I use my phone for and decided my usage could be distilled into three things: a VPN, a browser, and some way to interact with Org files (my recipe project described in a previous post is working great). I'm pretty sure the first two are covered in at least Mobian, but I need an alternative to Orgzly.
After some searching, I discovered Organice, which appears to do everything Orgzly does and more. The main difference is Organice pulls Org files down from Dropbox, Google Drive, or WebDAV; whereas Orgzly looks at files on disk, so an external program (such as Syncthing) is required for syncing. Part of the point of moving to a Pine phone is to escape Google, so Drive was out; I don't have particularly strong feelings about Dropbox, but I figured where's the fun in taking the easy way out? My one concern, though, is that I've got a pretty good flow working with Syncthing, and I'm not exactly sure what my workflow will look like for WebDAV.
I was further compelled to try WebDAV when I read that NGINX can host a WebDAV server if you install the full version, which I happened to have installed on Super Pi. After a little more research, I SSHd into Super Pi, and started slapping some config together in /etc/nginx/sites-available/webdav. A blog post here got me most of what I needed, my first iteration got me this server block:
server {
listen 80;
server_name webdav.my.local;
autoindex on;
root /var/www/html/files/;
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
dav_access user:rw group:rw all:r;
dav_methods PUT DELETE MKCOL COPY MOVE;
dav_ext_methods OPTIONS PROPFIND;
client_body_temp_path /tmp/client-bodies;
client_max_body_size 0;
create_full_put_path on;
}
Super Pi is already configured to proxy domains to various servers, I just had to go into Pi-Hole and set webdav.my.local to proxy to the PI's IP, 192.168.0.23. auth_basic was also conveniently already set up thanks to Pi-Hole, so I decided to use the existing file here as well. The only extra stuff I had to do was make the /var/www/html/files/ folder. I did get mixed up on basic permissions and forgot that execute permissions were required to open a folder, but this got me sorted:
sudo chown www-data:www-data files
sudo chmod 775 files
With a quick sudo nginx -t
followed by a sudo systemctl restart nginx
I was able to open my Files app, go to Other Locations, and in the bottom there is a Connect to server prompt with a text box that I entered dav://webdav.my.local, and immediately got the prompt to sign in.
Organice
Getting Organice to connect to my WebDAV server was a little more involved, though. I toyed with pulling down Organice's source code and hosting it myself, but one of the JavaScript libraries threw up warnings about not running on ARM or something, so I scrapped that and decided to just go through organice.200ok.ch. There were two issues to resolve, plus one more secret issue that took me a long time to figure out.
The first issue was that Organice was hosted on HTTPS, so my WebDAV server had to be, too. Resolving this was easy, I just had to copy over the SSL settings from every other service I was proxying:
listen 443 ssl;
ssl_certificate /etc/ssl/certs/my.domains.local.crt;
ssl_certificate_key /etc/ssl/private/my.domains.local.key;
ssl_protocols TLSv1.2;
ssl_ciphers HIGH:!aNULL:MD5;
The second issue was that Organice is purely client-side, so the connections to my WebDAV server were done via client-side JavaScript which triggers CORS issues. Resolving this was fairly straightforward, Organice's documentation had most of this worked out already:
add_header 'Access-Control-Allow-Origin' * always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, OPTIONS, MOVE, DELETE, PROPFIND' always;
add_header 'Access-Control-Allow-Headers' 'Origin,Accept,X-Requested-With,Content-Length,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization,X-CSRF-Token,Depth' always;
add_header 'Access-Control-Allow-Credentials' true always;
The secret issue was that the WebDAV library Organice used didn't play nice with NGINX's built-in basic auth, so I had to remove the two auth_basic lines from my NGINX configuration. This was a little disappointing, but authentication has always been a nice-to-have since this is all on my local network and behind a VPN.
In the end, my NGINX configuration turned into this:
server {
listen 443 ssl;
ssl_certificate /etc/ssl/certs/my.domains.local.crt;
ssl_certificate_key /etc/ssl/private/my.domains.local.key;
ssl_protocols TLSv1.2;
ssl_ciphers HIGH:!aNULL:MD5;
server_name webdav.my.local;
autoindex on;
client_body_temp_path /tmp/client-bodies;
client_max_body_size 0;
add_header 'Access-Control-Allow-Origin' * always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, OPTIONS, MOVE, DELETE, PROPFIND' always;
add_header 'Access-Control-Allow-Headers' 'Origin,Accept,X-Requested-With,Content-Length,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization,X-CSRF-Token,Depth' always;
add_header 'Access-Control-Allow-Credentials' true always;
root /var/www/html/files/;
# auth_basic "Restricted";
# auth_basic_user_file /etc/nginx/.htpasswd;
dav_methods PUT DELETE MKCOL COPY MOVE;
dav_ext_methods OPTIONS PROPFIND;
dav_access user:rw group:rw all:r;
create_full_put_path on;
}
The only annoying thing now is that on mobile I have to use Firefox beta and toggle a setting in about:config called security.enterprise_roots.enabled to true. The setting always reverts to false and it's becoming a pain to switch it all the time. When I eventually get a Pine phone, I think this will be an easy problem to fix, but on Android it's a bit of a pain.
Back to Orgzly
When I set up my repositories in Orgzly previously (in the main menu, under settings, then under sync, then once more under repositories), I completely missed that there was a WebDAV option when you hit the button to add a repository. The configuration is straightforward: simply provide the URL and in this case a bogus username and password (since auth isn't configured). Since the WebDAV is hosted locally over HTTPS, a certificate must be added even though the certificate authority is already installed on the operating system's certificate store per Super Pi Part 6. I used the same script to generate a new certificate that I provided to Orgzly. Here's the script:
openssl -x509 -req -in my.domains.local.csr -CA /home/pi/openssl/auth/myCA.pem -CAkey /home/pi/openssl/auth/myCA.key -CAcreateserial -out my.domains.local.crt -days 1825 -sha256 -extfile my.domains.local.ext
After copying the contents of the output file my.domains.local.crt to the certificate field in Orgzly, a connection can be made and Org files can be read.