-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
[API] Commenting through a token #1513
Conversation
Generated by 🚫 Danger |
Sounds good -- plus a test; i added a token to the If you're creating a whole new method instead of shoehorning it into the existing one, maybe this is best to put into a new API file after all? Your call. I like the idea of the username, but lookup by token isn't that bad, esp. if we only search users that have |
@jywarren I'm more concerned by the security problem here.
However, if the API accepts any token and looks up the user, the possibility will increase to n/2^16 where n is the number of users with EDIT: I made a calculation mistake. I counted 16 bits instead of bytes, which is only 2 bytes of entropy and an awfully bad idea. Instead, on an individual basis, there a 1/2^128 chance instead which translates to approximately 2.9387359e-39, and for 10,000 users, it is 2.9387359e-35 instead which is more like 2.9387359e-33%, so on a second look that might not me THAT bad an idea. However, I see no harm with being a little more cautious. |
P.S. I added a new function so that we could point the |
Ah ok, good point. Sounds good!
…On Jul 8, 2017 2:25 PM, "Ujjwal Sharma" ***@***.***> wrote:
P.S. I added a new function so that we could point the comment_by_token
function to a more appropriate URL inside config/routes.rb. (Possibly
something like /api/comment. It would be a good idea IMO to group all the
API routes together with an /api/ prefix. What do you say?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1513 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AABfJ4AAqXl6aplCxroE-StzfphaM9uFks5sL8mEgaJpZM4OR0j4>
.
|
On both counts.
On Jul 8, 2017 2:28 PM, "Jeffrey Warren" <[email protected]> wrote:
Ah ok, good point. Sounds good!
…On Jul 8, 2017 2:25 PM, "Ujjwal Sharma" ***@***.***> wrote:
P.S. I added a new function so that we could point the comment_by_token
function to a more appropriate URL inside config/routes.rb. (Possibly
something like /api/comment. It would be a good idea IMO to group all the
API routes together with an /api/ prefix. What do you say?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1513 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AABfJ4AAqXl6aplCxroE-StzfphaM9uFks5sL8mEgaJpZM4OR0j4>
.
|
@jywarren if I have reference to user |
Oh, wait. I could do |
But please try to use user instead, if possible. We want to deprecate
DrupalUsers soon. Either try to switch over entirely or you can add an
adapter method to DrupalUsers aliasing token, so you can do
drupal_user.token, see?
Thanks!
…On Jul 8, 2017 3:18 PM, "Ujjwal Sharma" ***@***.***> wrote:
Oh, wait. I could do @user.user.token. Thanks.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1513 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AABfJ3q8Lux1ykSDwJxxtRXs6ITm5Dhjks5sL9X5gaJpZM4OR0j4>
.
|
@jywarren I will. Was using |
Ah, so, User.find_by_username should work!
…On Jul 8, 2017 3:27 PM, "Ujjwal Sharma" ***@***.***> wrote:
@jywarren <https://github.com/jywarren> I will. Was using DrupalUsers for
the find_by_name function.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1513 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AABfJx3w77YXvGYbLpjn0FTECQvtG4xLks5sL9glgaJpZM4OR0j4>
.
|
Awesome. Will use that instead. |
@jywarren how does this look? Should I wrap the commenting logic inside the |
@jywarren It finally works now, I just forgot the comma inside the hash literal. Could you please guide me regarding the last question I asked so that I could continue working on this? |
Sure, a shared private function sounds great. |
@jywarren started to work on the private function, it is mostly on the lines of the regular function. Hopefully, if its well tested, it will be super easy for me to make just the right function. The problem is, I had trouble understanding this part: respond_with do |format|
if params[:type] && params[:type] == 'question'
@answer_id = 0
format.js
else
format.html do
if request.xhr?
render partial: 'notes/comment', locals: { comment: @comment }
else
flash[:notice] = 'Comment posted.'
redirect_to @node.path + '#last' # to last comment
end
end
end I would start digging into it, but if you get the time, could you explain what exactly is achieves? I will then add some comments, I guess. That would be great for later contributors. |
@jywarren Take a look now. If you like it, I would start writing unit tests for it. Hopefully, we could get it merged by today. |
class CommentError < ArgumentError | ||
end | ||
|
||
def create_comment(node, user, body) |
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 type of logic should go in helpers. Keep the controller code as thin as possible. Only keep action related methods
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.
Okay, If @jywarren approves the function, I would move it to the corresponding helper class.
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.
Maybe look at how we've done error responses in other parts of the code, and compare also with best practices from modern Rails guides?
format.js lets you create a response to a request with format = js, so ending in ".js" in the uRL. Chris is also a way to specify that it's an asynchronous xhr request, most likely from a JavaScript ajax function and not an html form request. So that code is helping respond to different types of requests but giving essentially the same information. |
if @user && @user.token == @token | ||
begin | ||
@comment = create_comment(@node, @user, @body) | ||
msg = { |
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.
I guess this just has a /lot/ of repeated code here -- the only unique line in 52-59 vs 61-68 vs 71-78 is :created
and "Created"
, you know? If you're going through the trouble to a whole new class for CommentError, i just feel that it's not justified given how little this code is reducing repetition. Also, isn't it a bit odd to need to begin/rescue
in here?
I'm trying to find a guide to best-practices in Rails controller error handling, to help DRY out this code. But I'm not finding much that's not based on model validation error handling...
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.
I get your point. I used the raise -> rescue
workflow here because I call the @comment.save
inside the function but wanted the calling function to know that something went wrong and do something sensible, and decided that throwing an error would be the best possible way to achieve this. If you could suggest a better way, I would be more than happy to use it instead, though.
@jywarren wrote a basic test. I have no idea why, but the test fails because the response is not |
Re the If so, i think you can set a more specific (narrower) path higher in the routes.rb file and it'll catch ones that fit the pattern |
@jywarren got it, will definitely add it higher up. |
Maybe you could pass back the output of `.save` and then you'd have the
built-in ActiveRecord exceptions to work with?
…On Sun, Jul 9, 2017 at 4:45 PM, Ujjwal Sharma ***@***.***> wrote:
@jywarren <https://github.com/jywarren> got it, will definitely add it
higher up.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1513 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AABfJ_dsu_TwzGJvxwqxPQr7aL8lSCYdks5sMTvzgaJpZM4OR0j4>
.
|
@jywarren I failed to figure out the reason I was getting an HTTP |
@jywarren figured out a solution 🎉 https://stackoverflow.com/questions/45005178/rails-responds-with-status-code-406/45013651#45013651 Will push my changes now and will accept the answer after 2 days. |
Ah one more thing -- did you want to display tokens to logged-in users on their profiles, and to admins for all profiles? You could make it show only during a |
@jywarren Yes. Showing the token only when the user explicitly asks for it sounds perfect. |
@jywarren I was curious. When can |
@jywarren figured it out. Check out the three tests I added. Do we need 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.
Looking good -- almost there! I think you could include the profile token display in this PR if you like.
@node = Node.find params[:id] | ||
@user = User.find_by_username params[:username] | ||
@body = params[:body] | ||
@token = request.env['rack.session']['token'] |
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.
What are the advantages of this over passing the token in a POST req?
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.
I will look around for the best practices regarding tokens and come back to you. AFAIK, there's an important security benefit of passing the auth token inside the header, but I totally forgot what it was. 😅
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.
https://www.codeschool.com/blog/2014/02/03/token-based-authentication-rails/ says that there's an inbuilt Rails function for dealing Authorization tokens "the right way".
It goes like:
authenticate_or_request_with_http_token do |token, options|
# authenticate user...
end
should we use it instead?
|
||
if @user && @user.token == @token | ||
begin | ||
@comment = create_comment(@node, @user, @body) |
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.
Maybe add a comment here telling where to find this method? I think for newcomers the Rails organization can be a bit arcane and although it adds a line, this could be really helpful for some.
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.
Sure, will do.
config/routes.rb
Outdated
@@ -3,13 +3,15 @@ | |||
mount JasmineRails::Engine => '/specs' if defined?(JasmineRails) | |||
mount JasmineFixtureServer => '/spec/javascripts/fixtures' if defined?(Jasmine::Jquery::Rails::Engine) | |||
|
|||
# Manually written API functions | |||
post '/bot/comment/id.:format', to: 'comment#create_by_token' |
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.
i'd prefer this to be more general -- anyone developing an API use -- could we do /comment/create/token/:id.:format
maybe?
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.
Definitely. This was a placeholder anyway, because I realized that there would be a few issues with the /api
endpoint because it's already being used.
let's not - your implementation is clean and readable enough that we
needn't worry. I hadn't seen that before and some Rails conventions are
more widely adopted than others. Sometimes they're obscure enough to
actually make using them harder :-P
…On Mon, Jul 10, 2017 at 1:16 PM, Ujjwal Sharma ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In app/controllers/comment_controller.rb
<#1513 (comment)>:
> flash[:error] = 'The comment could not be saved.'
render text: 'failure'
end
end
+ def create_by_token
+ @node = Node.find params[:id]
+ @user = User.find_by_username params[:username]
+ @Body = params[:body]
+ @token = request.env['rack.session']['token']
https://www.codeschool.com/blog/2014/02/03/token-based-
authentication-rails/ says that there's an inbuilt Rails function for
dealing Authorization tokens "the right way".
It goes like:
authenticate_or_request_with_http_token do |token, options|
# authenticate user...end
should we use it instead?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1513 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AABfJ5VIeOybJRdhWNkaI6aGeOb6DrW0ks5sMlx9gaJpZM4OR0j4>
.
|
@jywarren Agreed. I will push a commit for the other two things you pointed out, and hopefully, we'd probably get this show on the road today. |
@jywarren made the suggested changes. Take a look. |
@jywarren merge this whenever you're ready, I see you have approved the changes but I do not have access to the repo so I cannot do it myself. 😅 |
Great work guys! |
Thanks, @ananyo2012. Hopefully, this will clear the way for a few basic publiclab-related behaviors, especially ones that involve simple commenting. |
Yes you can move on with the publiclab/plotsbot#13 after this is merged. |
Merging! Thanks -- can you add to |
@jywarren take a look. The function does not do anything yet, but a laid out a possible flow about how it could work. Maybe you had something else in mind? I'd be happy to incorporate your suggestions.