Support automatic license updates and manual license uploads.
Review Request #14405 — Created April 28, 2025 and updated
The new Licenses page now triggers update checks for licenses on load.
This process involves:
POSTing to the Licenses page with a request for a license check.
The License Provider will either provide an opaque payload that can
be used for communicating with an external licensing server, or a
flag stating that checks aren't supported.POSTing to the licensing server with the payload.
POSTing back to the Licenses page with the response from the
licensing server.The License Provider will process the result, which may involve
installing a new license or altering the current one.This whole process is designed to keep the details of any license
updates internal to the License Provider and licensing server. The
state is communicated in the UI, and the license information reloaded
from new attributes provided in the License Provider responses.Along with this, licenses can be manually updated, if specified in the
license information. When enabled, this will show a button for uploading
a license, which will pop up a file chooser. After selecting a file, the
contents will be sent to the License Provider for processing via a POST
to the Licenses page.The view for the Licenses page handles all POST requests. It requires a
CSRF token and some identifying information on the action, action target
(license provider and license), and arguments. It then dispatches to the
License Provider and handles any responses or error results.Right now, there are specific actions that are supported by this view.
The longer-term plan is to enable arbitrary action support, so License
Providers can trigger custom behavior automatically or in response to
user actions.
All Python and JavaScript unit tests pass.
Tested manually uploading valid and invalid licenses for Power Pack
(ported to the new architecture), verifying the results.Tested automatic license updates for Power Pack.
Tested all error results and display.
Summary | ID |
---|---|
4583d3adb531b047e35dcfe3297f08a989258e67 |
Description | From | Last Updated |
---|---|---|
Just a note that I don't see the review request where all of the license action handling functions were added … |
![]() |
|
undefined name 'HttpResponse' Column: 10 Error code: F821 |
![]() |
|
Swap these. |
|
|
Agreement isn't right here. Should either be "There are no ... guarantees" or "There is no ... guarantee" |
|
|
Should we log something here? |
|
|
undefined name 'RequestCheckLicenseResult' Column: 10 Error code: F821 |
![]() |
|
We can get rid of the not action part of this check since we checked it above. |
![]() |
|
This sentence doesn't make sense. |
![]() |
|
This should say "check_response_data". |
![]() |
|
Can we change the error message here to match the log message here? Otherwise it's a bit redundant given the … |
![]() |
|
I notice this is the only place where we're setting a status in the payload. Should we be doing this … |
![]() |
|
There's no sanity check here? Looks like a copy-pasto. |
![]() |
|
This should be removed. |
![]() |
- Change Summary:
-
Added a missing typing import lost in the code split.
- Commits:
-
Summary ID ace1682608d31e7b2f6599b985f42ea5bfbda75a 8f7211ab72c2f394a66a46e2d0ffbc45fcf24043 - Diff:
-
Revision 2 (+3500 -2)
Checks run (2 succeeded)
- Change Summary:
-
- Fixed an import location.
- Fixed some bad grammar in a docstring.
- Commits:
-
Summary ID 8f7211ab72c2f394a66a46e2d0ffbc45fcf24043 da39261ee70d6510d7b2861150a83d58e57ec982 - Diff:
-
Revision 3 (+3522 -8)
- Change Summary:
-
Added a missing type checking import.
- Commits:
-
Summary ID da39261ee70d6510d7b2861150a83d58e57ec982 4583d3adb531b047e35dcfe3297f08a989258e67 - Diff:
-
Revision 4 (+3524 -8)
Checks run (2 succeeded)

-
-
Just a note that I don't see the review request where all of the license action handling functions were added to
BaseLicenseProvider
. -
-
-
-
Can we change the error message here to match the log message here? Otherwise it's a bit redundant given the error message below that catches this one.
-
I notice this is the only place where we're setting a status in the payload. Should we be doing this anywhere else?
-
-