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

[API] Commenting through a token #1513

Merged
merged 14 commits into from Jul 11, 2017
39 changes: 35 additions & 4 deletions app/controllers/comment_controller.rb
@@ -1,4 +1,6 @@
class CommentController < ApplicationController
include CommentHelper

respond_to :html, :xml, :json
before_filter :require_user, only: %i[create update delete]

Expand All @@ -12,9 +14,11 @@ def index
# create node comments
def create
@node = Node.find params[:id]
@comment = @node.add_comment(uid: current_user.uid, body: params[:body])
if current_user && @comment.save
@comment.notify(current_user)
@body = params[:body]
@user = current_user

begin
@comment = create_comment(@node, @user, @body)
respond_with do |format|
if params[:type] && params[:type] == 'question'
@answer_id = 0
Expand All @@ -30,12 +34,39 @@ def create
end
end
end
else
rescue CommentError
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']
Copy link
Member

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?

Copy link
Member Author

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. 😅

Copy link
Member Author

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
# The create_comment is a function that has been defined inside the
# CommentHelper module inside app/helpers/comment_helper.rb and can be
# used in here because the module was `include`d right at the beginning
@comment = create_comment(@node, @user, @body)
respond_to do |format|
format.all { render :nothing => true, :status => :created }
end
rescue CommentError
respond_to do |format|
format.all { render :nothing => true, :status => :bad_request }
end
end
else
respond_to do |format|
format.all { render :nothing => true, :status => :unauthorized }
end
end
end

# create answer comments
def answer_create
@answer_id = params[:aid]
Expand Down
14 changes: 14 additions & 0 deletions app/helpers/comment_helper.rb
@@ -0,0 +1,14 @@
module CommentHelper
class CommentError < ArgumentError
end

def create_comment(node, user, body)
@comment = node.add_comment(uid: user.uid, body: body)
if user && @comment.save
@comment.notify user
return @comment
else
raise CommentError.new()
end
end
end
4 changes: 3 additions & 1 deletion config/routes.rb
Expand Up @@ -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 '/comment/create/token/id.:format', to: 'comment#create_by_token'

#Search RESTful endpoints
#constraints(subdomain: 'api') do
mount Srch::API => '/api'
mount GrapeSwaggerRails::Engine => '/api/d1ocs'
#end


resources :rusers
resources :user_sessions
resources :images
Expand Down
51 changes: 50 additions & 1 deletion test/functional/comment_controller_test.rb
Expand Up @@ -53,7 +53,7 @@ def teardown
end
assert_response :success
assert_not_nil :comment
#assert_template partial: 'wiki/_comment'
#assert_template partial: 'wiki/_comment'
#should uncomment above once comment displaying partial is implemented for wikis.
end

Expand Down Expand Up @@ -251,4 +251,53 @@ def teardown
assert ActionMailer::Base.deliveries.collect(&:to).include?([rusers(:moderator).email])
# tag followers can be found in tag_selection.yml
end

test 'should not post comment through invalid token successfully' do
@params = {
id: 1,
body: 'Test Comment',
username: 'Bob',
format: 'json'
}

@headers = {
'token' => 'invalid-token'
}

post :create_by_token, @params, @headers
assert_response :unauthorized
end

test 'should not post an invalid comment successfully' do
@params = {
id: 1,
body: '',
username: 'Bob',
format: 'json'
}

@headers = {
'token' => 'abcdefg12345'
}

post :create_by_token, @params, @headers
assert_response :bad_request
end

test 'should post comment through valid token successfully' do
@params = {
id: 1,
body: 'Test Comment',
username: 'Bob',
format: 'json'
}

@headers = {
'token' => 'abcdefg12345'
}

post :create_by_token, @params, @headers
assert_response :success
end

end