|Recipients||marcus.priesch, rouilj, schlatterbeck|
Hi Marcus: In message <email@example.com>, 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.
|2022-05-05 13:54:47||rouilj||set||recipients: + rouilj, schlatterbeck, marcus.priesch|
|2022-05-05 13:54:47||rouilj||link||issue2551203 messages|