Previously, we relied on a third-party API provided by Google to
generate the QR codes used to setup a 2FA application. This API has been
disabled, so we are left with two options: we either switch to another
API provider (and there seems to be no QR code generation API provided
by a well-known source, so we'd have to rely on an unknown party to
provide an API which at best may or may not work and at worst generates
malicious QR codes) or we generate our own QR codes.
Thankfully, there exists a popular and relatively well-maintained Python
library for QR code generation, so it's relatively straightforward to
generate the QR code ourselves and use a data: URL to return the
generated QR code to the browser. This way, we don't even have to store
any temporary files -- the PNG is kept entirely in memory, and only for
the duration of the qrcode_url() function.
Since SSO runs on xenial (for now), we're stuck using Python 3.5.
Unfortunately, the latest version of qrcode only supports Python >= 3.7.
Thankfully, there is another option: segno.
The disadvantage of this library is that it is less well-known. However,
it is still actively maintained, and actually allows the code to be even
shorter as it natively supports generating data: URLs from the generated
QR code.
Previously, we relied on a third-party API provided by Google to
generate the QR codes used to setup a 2FA application. This API has been
disabled, so we are left with two options: we either switch to another
API provider (and there seems to be no QR code generation API provided
by a well-known source, so we'd have to rely on an unknown party to
provide an API which at best may or may not work and at worst generates
malicious QR codes) or we generate our own QR codes.
Thankfully, there exists a popular and relatively well-maintained Python
library for QR code generation, so it's relatively straightforward to
generate the QR code ourselves and use a data: URL to return the
generated QR code to the browser. This way, we don't even have to store
any temporary files -- the PNG is kept entirely in memory, and only for
the duration of the qrcode_url() function.