Roundup Tracker - Issues

Message7510

Author rouilj
Recipients marcus.priesch, rouilj, schlatterbeck
Date 2022-05-05.13:54:46
Message-id <20220505135442.47A626A0289@pe15.cs.umb.edu>
In-reply-to <52323af0-99c1-043d-4573-c954f914f52c@priesch.co.at>
Hi Marcus:

In message <52323af0-99c1-043d-4573-c954f914f52c@priesch.co.at>,
Marcus Priesch writes:
>the problem is that the preflight request comes without any
>authorization (because it is asking the server what is allowed) and
>therefore it always returns 403.

Hmm, have you tried making a credentialed request?

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#requests_with_credentials
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#sending_a_request_with_credentials_included

So rather than a simple fetch to /rest/issue/23 you do a credentialed
fetch there.

I would think you would have to do that anyway as /rest/issue/23 may
not be readable to anonymous (you can control permission on a class
(e.g. can't access any user item), an item (you can access only your
user item), or property (you can't access the Role property of your
user item). All three of these are exposed as endpoints in the REST
interface.

>in client.py line 652 (with the patch applied) it reads:
>
>if not self.db.security.hasPermission('Rest Access', self.userid):
>     self.response_code = 403
>
>user is "anonymous" here as we have no auth data in the preflight request.

Does it work with a non-credentialed preflight if anonymous has 'Rest
Access' permission? (See below for how to enable.)

>thats what the patch in client.py (below "# handle preflight...")
>addresses.
>
>at this point the patch allow everything that is supported down the way
>(hopefully), assuming that at deeper levels somewhere things get
>forbidden based on permissions and other rules.

You are correct that a delete against /rest/issue would be rejected
regardless of what CORS reports. However if somebody codes an
interface that trusts what CORS reports it could get ugly by showing
users things that will not work.

>	@Routing.route("/data/<:class_name>", 'OPTIONS')
>
>section never gets hit at this point, because it only would if someone
>has "Rest Access" permission. which anonymous dont has.

We could add a "CORS Access" right and check to see if it's an OPTIONS
with the proper header subset (Allow-*). So your patch would not
perform the response but would permit the request to bypass the 403. (1)

However if anonymous is not allowed Rest Access, you will have to pass
credentials when performing the actual POST/DELETE/PUT/GET call. So
the credentials for the rest end point should be passed for CORS as
well.

>but maybe it should for that reason ? maybe that would be too open ?

Currently the Anonymous user has "Web Access" rights in almost all
cases otherwise you can't log in. They may still be unable to see any
data (due to the permissions model). For anybody implementing a REST
based front end I think anonymous should have REST access.

Consider the roundup-tracker. Anonymous is allowed read only access to
issues. Implementing the same via rest would have to allow anonymous
"Rest Access" permissions.

Simply add:

  db.security.addPermissionToRole('Anonymous', 'Rest Access')

at the end of schema.py and restart the server.

>maybe anonymous should just have enough permission to reach the code
>above to send correct cors headers? - which probably would be better
>than sending one answer for all ? ... but i am not that deep in the
>permission thing if this is possible :(

We would need to add a patch as in (1).

>acc. to max-age i found out that Access-Control-Max-Age indeed is a time
>saver when you access same endpoint within the time range as the OPTIONS
>request then gets not sent by the browser. maybe this should be
>configurable for the user ?

For right now, hard code the lifetime to say a week or so. I think
this is ok since:

  1. the access data is static. The only way the permissions can
     change is by changing the schema and restarting the server.

  2. if the cached access settings are invalid (become stale) the client
     will make a request that returns a 403 or other error. This isn't
     great but if it only occurs after permissions are changed it should
     not occur often.

So there is no security or data integrity issues with caching the
Access results too long. If we need to make that configurable in
config.ini or extract it into something that can be overridden using
interfaces.py we can discuss it when we see the need.

>[...] What use cases do you have in mind?
>> Would Roundup supply HTML partials/fragments to be composed on the
>> client?
> [...]
>i dont have anything in mind, but i can imagine someone building a
>frontend requesting html fragments (maybe running through tal for
>i18n ;)) or something else ...

Ok, so my scenario isn't totally crazy.

>i am rather thinking about where to put the code to address all possible
>use cases at once ...

I am not sure that is possible to do accurately.

  1. for rest we need to parse the route to determine if it's valid
     endpoint (rest/isue for example should fail)
  2. for rest we should to return only supported methods (e.g. not
     include DELETE for collection endpoints)
  3. for xmlrpc it only supports POST
  4. for http, the verb I think is only GET or POST. The actual verb
     is defined in the @action component of the query string.
     It's not even determined by a path component in the
     URL. So create is @action=new and retire/delete is @action=retire.

>when you say xmlrpc is working over post - hmmm, i dont think it would
>be needed because most likely there will be no browser talking to it ...
>but can be, if someone is wierd enough to build a webpage using xmlrpc
>instead of rest ;)

True, today you would probably use the rest endpoint and not XMLRPC,
but in AJAX, the X is XML. (FYI the rest endpoint can return XML by
adding a python module and setting the client content headers.)

>in the end it's all just plain http requests ... so i would vote to have
>the CORS thing for all http requests.

Well CORS is used to determine what verbs are valid for an endpoint.
XMLRPC and HTTP/html use a very restricted set of verbs in general.
History
Date User Action Args
2022-05-05 13:54:47rouiljsetrecipients: + rouilj, schlatterbeck, marcus.priesch
2022-05-05 13:54:47rouiljlinkissue2551203 messages
2022-05-05 13:54:46rouiljcreate