Message8024
While developing the replacement classhelper web component, we needed to get a list
of roles defined in the database. The template driven classhelper has a drop down
list of roles that can be used when searching the user class.
To replicate that with the web component classhelper, we needed to get a list
from the rest interface. Because roles are defined as a string property of
user and not a multilink, we can't query /rest/data/roles and get a list of roles.
I tried to fake the /data/roles endpoint in interfaces.py using:
from roundup.rest import Routing, RestfulInstance, _data_decorator
class RestfulInstance:
@Routing.route("/roles", 'GET')
@Routing.route("/data/roles", 'GET')
@_data_decorator
def get_roles(self, input):
"""Return all defined roles. The User class property
roles is a string but simulate it as a MultiLink
to an actual Roles class.
"""
return 200, {"collection": [{"id": rolename, "name": rolename.capitalize()}
for rolename in sorted(list(self.db.security.role.keys()))]}
but the default rule mapped to "/data/{:class:}" takes priority and caused /data/roles
to throw an error as there is no roles class.
If I modify rest.py with this patch:
--- a/roundup/rest.py Tue Apr 30 22:27:57 2024 -0400
+++ b/roundup/rest.py Tue Apr 30 22:44:33 2024 -0400
@@ -399,7 +399,9 @@
# find the rule match the path
# then get handler match the method
- for path_regex, funcs in cls.__route_map.values():
+ seq = [(path_regex, funcs) for path_regex, funcs
+ in cls.__route_map.values()]
+ for path_regex, funcs in reversed(seq):
# use compiled regex to find rule
match_obj = path_regex.match(path)
if match_obj:
to reverse the order of application of the roles, my definition of
/data/roles is found first and it works. But the original order
is not deterministic. That makes my patch reversing the order, fragile.
The /roles endpoint does return the roles in the correct shape, but the library methods
used in the web component expect to hit /data/ so this is a bit of a refactor for them.
I have a couple of ideas on how to do this.
1. have two groups of routes and have interfaces.py call Route.route_first
that is processed first by the router. If no match is found, you use the
built in routes.
2. Allow Routing.route to support an order parameter like registering detectors.
Other ideas?
The web component project ticket: https://github.com/UMB-CS-682-Team-03/tracker/issues/33 |
|
Date |
User |
Action |
Args |
2024-05-01 02:54:31 | rouilj | set | recipients:
+ rouilj |
2024-05-01 02:54:30 | rouilj | set | messageid: <1714532070.93.0.92873216094.issue2551344@roundup.psfhosted.org> |
2024-05-01 02:54:30 | rouilj | link | issue2551344 messages |
2024-05-01 02:54:30 | rouilj | create | |
|