Require authentication for facility CSV downloads and log requests #697
Conversation
87f3ed7
to
d11a68b
Compare
Setting this up to take a look! |
src/app/src/actions/logDownload.js
Outdated
createAction('COMPLETE_LOG_DOWNLOAD'); | ||
|
||
export function logDownload(rows, callback) { | ||
return (dispatch) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the facilities data lives in the app's Redux store state, conceivably we could change this function to actually perform the download directly rather than having to pass rows
and callback
in as arguments. If we handled it this way, we could get the facilities data here via getState
and then directly import the downloadFacilitiesCSV
utility function to execute it in the promise chain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We discussed this in person and it does make sense given the future refactoring of the search result handling to have this action fetch the results from the state rather than having the caller pass them in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented in fixup c53103b
src/app/src/actions/logDownload.js
Outdated
.then(() => { | ||
callback(rows); | ||
return dispatch(completeLogDownload()); | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick but consider
.then(() => callback(rows))
.then(() => dispatch(completeLogDownload())
.catch....
Or whatever similar construction would work with a potential revision to use getState.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented in fixup c53103b
help_text='The User account that made the request' | ||
) | ||
path = models.CharField( | ||
max_length=2083, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is 2083 a maximum value for paths?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a well researched StackOverflow answer that contributed to this choice of maximum value
https://stackoverflow.com/a/417184
In summary, URLs larger than this bump into some limits in browsers and search crawling infrastructure so it is a reasonable maximum value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 This worked well! I saw the dialog prompting me to login when I tried to download the CSV without logging in, and I see the downloadlog record created after logging in & downloading the CSV:
openapparelregistry=# SELECT * FROM api_downloadlog;
id | path | record_count | created_at | updated_at | user_id
----+-------------+--------------+-------------------------------+-------------------------------+---------
1 | /facilities | 500 | 2019-07-24 18:37:56.752855+00 | 2019-07-24 18:37:56.752905+00 | 1
(1 row)
I made a comment about a small refactor that I think might clean up the download code: essentially, since the CSV rows originate from the Redux store data, we can do all of the CSV downloading work in the new logDownload
action by accessing the store with getState
and then calling the proper utility functions. On one hand it'd help make the code a little easier to reason about; on the other I don't know how likely it is that we'll add more new features around this part of the app -- so it may not be beneficial.
Feel free either to do that or not, depending on how soon you'd like to deploy the new release!
I tested this, btw without reconciling the merge conflict, which is just that one of the reducers on develop now has a different name than it does on this branch. |
d11a68b
to
f1ace56
Compare
Rebased to resolve the merge conflict. |
f1ace56
to
82c4321
Compare
Records will be written to this table when an authenticated user downloads a CSV from the web client.
CSVs are compiled on the client side, so we did not have an existing endpoint to which we could attach the new logging code.
Requiring authentication on the log endpoint effectively restricts downloads to registered users, which is what we want. Now that we are requiring users to log in before downloading a CSV we guide them to login/registration if they attempt to download without a session.
These were accidentally added.
c53103b
to
8227563
Compare
Thanks for the great architecture suggestions. The implementation is better for it. |
Overview
Require a login to download a facility CSV from the map page and log all CSV download requests to the database.
Connects #668
Demo
Notes
We have kept the method, model, and model attribute names relatively generic so we have the option of logging other downloads using the same code while avoiding the need to change names.
Testing Instructions
This assumes the fixture data has been loaded and processed with
./scripts/resetdb
c2@example.com
shoes
./scripts/manage dbshell
select * from api_downloadlog
and verify that thepath
andrecord_count
columns match../scripts/server
. Click "Download CSV" and verify that error toast is shown. Start./scripts/server
Checklist
fixup!
commits have been squashed