]> source.dussan.org Git - redmine.git/commitdiff
Allow authenticating with an API token via XML or JSON. (#3920)
authorEric Davis <edavis@littlestreamsoftware.com>
Wed, 23 Dec 2009 06:27:33 +0000 (06:27 +0000)
committerEric Davis <edavis@littlestreamsoftware.com>
Wed, 23 Dec 2009 06:27:33 +0000 (06:27 +0000)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@3218 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/controllers/application_controller.rb
app/controllers/news_controller.rb
test/integration/api_token_login_test.rb [new file with mode: 0644]

index 75f7121f2897e7b94fe1861523b84db256cfd099..40adff4bc06ba88c4233be383c36abd76d81218d 100644 (file)
@@ -70,6 +70,8 @@ class ApplicationController < ActionController::Base
     elsif params[:format] == 'atom' && params[:key] && accept_key_auth_actions.include?(params[:action])
       # RSS key authentication does not start a session
       User.find_by_rss_key(params[:key])
+    elsif ['xml', 'json'].include?(params[:format]) && params[:key] && accept_key_auth_actions.include?(params[:action])
+      User.find_by_api_key(params[:key])
     end
   end
   
@@ -114,7 +116,11 @@ class ApplicationController < ActionController::Base
       else
         url = url_for(:controller => params[:controller], :action => params[:action], :id => params[:id], :project_id => params[:project_id])
       end
-      redirect_to :controller => "account", :action => "login", :back_url => url
+      respond_to do |format|
+        format.html { redirect_to :controller => "account", :action => "login", :back_url => url }
+        format.xml { head :unauthorized }
+        format.json { head :unauthorized }
+      end
       return false
     end
     true
index 394b5182e92e84de7a84c1d27804a494fe38d4c3..53e0addf2546112fbbcc3be187bf450482953e33 100644 (file)
@@ -31,6 +31,8 @@ class NewsController < ApplicationController
                                    :order => "#{News.table_name}.created_on DESC"    
     respond_to do |format|
       format.html { render :layout => false if request.xhr? }
+      format.xml { render :xml => @newss.to_xml }
+      format.json { render :json => @newss.to_json }
       format.atom { render_feed(@newss, :title => (@project ? @project.name : Setting.app_title) + ": #{l(:label_news_plural)}") }
     end
   end
diff --git a/test/integration/api_token_login_test.rb b/test/integration/api_token_login_test.rb
new file mode 100644 (file)
index 0000000..4077403
--- /dev/null
@@ -0,0 +1,73 @@
+require "#{File.dirname(__FILE__)}/../test_helper"
+
+class ApiTokenLoginTest < ActionController::IntegrationTest
+  fixtures :all
+
+  # Using the NewsController because it's a simple API.
+  context "get /news.xml" do
+
+    context "in :xml format" do
+      context "with a valid api token" do
+        setup do
+          @user = User.generate_with_protected!
+          @token = Token.generate!(:user => @user, :action => 'api')
+          get "/news.xml?key=#{@token.value}"
+        end
+        
+        should_respond_with :success
+        should_respond_with_content_type :xml
+        should "login as the user" do
+          assert_equal @user, User.current
+        end
+      end
+
+      context "with an invalid api token (on a protected site)" do
+        setup do
+          Setting.login_required = '1'
+          @user = User.generate_with_protected!
+          @token = Token.generate!(:user => @user, :action => 'feeds')
+          get "/news.xml?key=#{@token.value}"
+        end
+        
+        should_respond_with :unauthorized
+        should_respond_with_content_type :xml
+        should "not login as the user" do
+          assert_equal User.anonymous, User.current
+        end
+      end
+    end
+
+    context "in :json format" do
+      context "with a valid api token" do
+        setup do
+          @user = User.generate_with_protected!
+          @token = Token.generate!(:user => @user, :action => 'api')
+          get "/news.json?key=#{@token.value}"
+        end
+        
+        should_respond_with :success
+        should_respond_with_content_type :json
+        should "login as the user" do
+          assert_equal @user, User.current
+        end
+      end
+
+      context "with an invalid api token (on a protected site)" do
+        setup do
+          Setting.login_required = '1'
+          @user = User.generate_with_protected!
+          @token = Token.generate!(:user => @user, :action => 'feeds')
+          get "/news.json?key=#{@token.value}"
+        end
+        
+        should_respond_with :unauthorized
+        should_respond_with_content_type :json
+        should "not login as the user" do
+          assert_equal User.anonymous, User.current
+        end
+      end
+    end
+    
+  end
+
+end