Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add endpoints to lock and unlock a document #5107

Merged
merged 5 commits into from Nov 6, 2019
Merged

Conversation

leenagupte
Copy link
Contributor

@leenagupte leenagupte commented Nov 4, 2019

Trello: https://trello.com/c/V17DA7ma
Follows on from: #4903

What's changed?

Add two imports to the Document Export API to "lock" and "unlock" a document.

The lock and unlock requests are only allowed for authenticated users who have the export permission.

Why?

A while ago we added the ability to lock a document in Whitehall to prevent a document from being edited in Whitehall during, and after, a migration. Should a migration fail we need the ability to unlock the document.

Results from local testing

Locking

curl -i -H "Content-Type: application/json" -H "Authorization: Bearer example" -X POST http://whitehall-admin.dev.gov.uk/government/admin/export/document/430652/lock

HTTP/1.1 204 No Content
Server: nginx/1.17.3
Date: Tue, 05 Nov 2019 16:09:53 GMT
Connection: keep-alive
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Cache-Control: no-cache
X-Request-Id: 97cd576e-45aa-4676-bbea-a66e625386bb
X-Runtime: 0.406012
Access-Control-Allow-Origin: *
Document.find(430652)
  Document Load (0.5ms)  SELECT  `documents`.* FROM `documents` WHERE `documents`.`id` = 430652 LIMIT 1
=> #<Document:0x000055bead9b26e0
 id: 430652,
 created_at: Sat, 02 Nov 2019 21:38:34 GMT +00:00,
 updated_at: Tue, 05 Nov 2019 16:09:53 GMT +00:00,
 slug: "18m-extension-to-opportunity-area-programme",
 document_type: "NewsArticle",
 content_id: "7104f52a-29c5-4597-ba96-eeceedff8a3e",
 locked: true>

Unlocking

curl -i -H "Content-Type: application/json" -H "Authorization: Bearer example" -X POST http://whitehall-admin.dev.gov.uk/government/admin/export/document/430652/unlock

HTTP/1.1 204 No Content
Server: nginx/1.17.3
Date: Tue, 05 Nov 2019 16:11:58 GMT
Connection: keep-alive
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Cache-Control: no-cache
X-Request-Id: 7a59c026-42a8-4c38-ab42-2cfa1384bc24
X-Runtime: 0.310073
Access-Control-Allow-Origin: *

 Document.find(430652)
  Document Load (0.8ms)  SELECT  `documents`.* FROM `documents` WHERE `documents`.`id` = 430652 LIMIT 1
=> #<Document:0x000055beada01b00
 id: 430652,
 created_at: Sat, 02 Nov 2019 21:38:34 GMT +00:00,
 updated_at: Tue, 05 Nov 2019 16:11:58 GMT +00:00,
 slug: "18m-extension-to-opportunity-area-programme",
 document_type: "NewsArticle",
 content_id: "7104f52a-29c5-4597-ba96-eeceedff8a3e",
 locked: false>

Add an endpoint to the export api to allow the document import process
to flag a document that's being imported as "locked" so that users are
not permitted to make any changes to it.

Ensures that only users with export data permissions can access this
endpoint.
Copy link
Member

@kevindew kevindew left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good - I've got a few suggestions that might allow reducing the number of changes needed for the same results.

def lock; end
def lock
document = Document.find(params[:id])
document.update(locked: true)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use the bang equivalent here so that it raises an error if the document fails validation rather than return a bool.

@@ -20,6 +20,8 @@ def lock
document = Document.find(params[:id])
document.update(locked: true)
head :no_content
rescue ActiveRecord::RecordNotFound
respond_with Hash.new, status: :not_found
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may not need this as ActiveRecord::RecordNotFound is an exception that Rails converts into a response. I've always found it hard to find a good link for this but you can find some details in the rescue responses section of https://guides.rubyonrails.org/configuring.html#configuring-action-dispatch

I'd suggest trying it out to see if it automatically does a 404 as I think it's unusual in the Whitehall codebase to rescue this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it returns a 404 without the rescue block. I'll remove this code.

assert document.reload.locked
assert_response :no_content
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


def no_content
head :no_content
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd have thought you don't really need to dry this up as someone reading this then has to look this method up to understand quite what no_content means which seems a bit unnecessary for a 6 character saving.

Doing a bit of Googling you might not actually need to specify head :no_content as Rails seems to have started doing that by default since Rails 5: rails/rails#19377

@@ -1,4 +1,5 @@
class Admin::Export::DocumentController < Admin::Export::BaseController
skip_before_action :verify_authenticity_token
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

A 204 No Content is returned if the lock request is successful.
[Rails 5](rails/rails#19377) does this by
default by automatically adding `:no_content` to the header if it can't
find a template to respond with.
Add an endpoint to the export api to allow the document import process
to "unlock" a document that's being imported if the import has failed
for any reason.

Ensure that only users with export data permissions can access this
endpoint.
A 204 No Content is returned if the unlock request is successful.
[Rails 5](rails/rails#19377) does this by
default by automatically adding `:no_content` to the header if it can't
find a template to respond with.
Authenticity token are generated as a hidden field in Whitehall forms. As it is not intended for these
POST routes to be called from a form within in the application, these check should be skipped.
@leenagupte
Copy link
Contributor Author

@kevindew Thanks for your comments. I've addressed them and fixed up.

Copy link
Member

@kevindew kevindew left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one!

@leenagupte leenagupte merged commit c94fb48 into master Nov 6, 2019
@leenagupte leenagupte deleted the lock-unlock-actions branch November 6, 2019 11:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants