From 286f1b876d2c6ba03f13426ff8e54e3d92661f3f Mon Sep 17 00:00:00 2001
From: Raphael Sofaer <raphael@joindiaspora.com>
Date: Fri, 20 May 2011 15:14:13 -0700
Subject: [PATCH] Allow anyone to generate a token, restrict tokens to
 ActivityStreams::PhotosController#create, don't let tokens create sessions.

---
 .../activity_streams/photos_controller.rb           |  2 +-
 app/controllers/tokens_controller.rb                |  8 +++-----
 app/models/user.rb                                  |  4 ----
 app/views/aspects/index.html.haml                   |  3 +--
 config/app.yml.example                              |  5 -----
 config/environment.rb                               | 12 ++++++++++++
 config/initializers/devise.rb                       |  2 ++
 features/logs_in_and_out.feature                    |  6 ++++++
 features/step_definitions/posts_steps.rb            |  6 ++++++
 spec/controllers/tokens_controller_spec.rb          | 13 ++-----------
 spec/controllers/users_controller_spec.rb           |  9 ++++++++-
 11 files changed, 41 insertions(+), 29 deletions(-)

diff --git a/app/controllers/activity_streams/photos_controller.rb b/app/controllers/activity_streams/photos_controller.rb
index 1369040a7f..aa36107940 100644
--- a/app/controllers/activity_streams/photos_controller.rb
+++ b/app/controllers/activity_streams/photos_controller.rb
@@ -13,7 +13,7 @@ class ActivityStreams::PhotosController < ApplicationController
     @photo = ActivityStreams::Photo.from_activity(params[:activity])
     @photo.author = current_user.person
     @photo.public = true
-    
+
     if @photo.save
       Rails.logger.info("event=create type=activitystreams_photo")
 
diff --git a/app/controllers/tokens_controller.rb b/app/controllers/tokens_controller.rb
index ca8a62f2f9..f50f0bbf8a 100644
--- a/app/controllers/tokens_controller.rb
+++ b/app/controllers/tokens_controller.rb
@@ -1,12 +1,10 @@
 class TokensController < ApplicationController
-  before_filter :redirect_unless_tokenable
-  def redirect_unless_tokenable
-    redirect_to root_url unless current_user.auth_tokenable?
-  end
-
   def create
     current_user.reset_authentication_token!
     current_user.authentication_token
     redirect_to token_path, :notice => "Authentication token reset."
   end
+  def show
+  end
 end
+
diff --git a/app/models/user.rb b/app/models/user.rb
index 1082eb558e..9ff8afecb8 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -326,10 +326,6 @@ class User < ActiveRecord::Base
     AppConfig[:admins].present? && AppConfig[:admins].include?(self.username)
   end
 
-  def auth_tokenable?
-    admin? || (AppConfig[:auth_tokenable].present? && AppConfig[:auth_tokenable].include?(self.username))
-  end
-
   protected
 
   def remove_person
diff --git a/app/views/aspects/index.html.haml b/app/views/aspects/index.html.haml
index d98923c379..95d5319853 100644
--- a/app/views/aspects/index.html.haml
+++ b/app/views/aspects/index.html.haml
@@ -22,8 +22,7 @@
 
   %h4.section.invite_friends
     != t('bookmarklet.explanation', :link => link_to(t('bookmarklet.explanation_link_text'), bookmarklet))
-  - if current_user.auth_tokenable?
-    %h4.section.invite_friends= link_to "Generate an authentication token for Cubbi.es", token_path
+  %h4.section.invite_friends= link_to "Generate an authentication token for Cubbi.es", token_path
   - if @invites > 0
     .section.invite_friends
       %h4= t('shared.invitations.invite_your_friends')
diff --git a/config/app.yml.example b/config/app.yml.example
index b7f529bed4..ce5feaaa3b 100644
--- a/config/app.yml.example
+++ b/config/app.yml.example
@@ -87,11 +87,6 @@ default:
   admins:
     - 'example_user1dsioaioedfhgoiesajdigtoearogjaidofgjo'
 
-  #List of users who can generate auth tokens
-  #Temporary so we can work on apps while oauth is being developed
-  auth_tokenable:
-    - 'iknowthatthismanualauthtokenthingisnoteasyorsecure'
-
   #s3 config, if set, carrierwave will store your photos on s3
   #s3_key: 'key'
   #s3_secret: 'secret'
diff --git a/config/environment.rb b/config/environment.rb
index 5db0d7a6fb..26adfb6b14 100644
--- a/config/environment.rb
+++ b/config/environment.rb
@@ -24,3 +24,15 @@ end
 
 # Initialize the rails application
 Diaspora::Application.initialize!
+
+# allow token auth only for posting activitystream photos
+module Devise
+  module Strategies
+    class TokenAuthenticatable < Authenticatable
+      private
+      def valid_request?
+        params[:controller] == "activity_streams/photos" && params[:action] == "create"
+      end
+    end
+  end
+end
diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb
index c55c139f07..65beed6daa 100644
--- a/config/initializers/devise.rb
+++ b/config/initializers/devise.rb
@@ -114,6 +114,7 @@ Devise.setup do |config|
   # ==> Configuration for :token_authenticatable
   # Defines name of the authentication token params key
   config.token_authentication_key = :auth_token
+  config.stateless_token = true
 
   # ==> Scopes configuration
   # Turn scoped views on. Before rendering "sessions/new", it will first check for
@@ -155,3 +156,4 @@ Devise.setup do |config|
   #   manager.default_strategies(:scope => :user).unshift :twitter_oauth
   # end
 end
+
diff --git a/features/logs_in_and_out.feature b/features/logs_in_and_out.feature
index b39b3e6828..baff416dda 100644
--- a/features/logs_in_and_out.feature
+++ b/features/logs_in_and_out.feature
@@ -14,3 +14,9 @@ Feature: user authentication
     And I click on my name in the header
     And I follow "log out"
     Then I should be on the home page
+
+  Scenario: user uses token auth
+    Given a user with username "ohai" and password "secret"
+    When I post a photo with a token
+    And I go to the aspects page
+    Then I should be on the new user session page
diff --git a/features/step_definitions/posts_steps.rb b/features/step_definitions/posts_steps.rb
index 4036f7524f..5ed9e08c1b 100644
--- a/features/step_definitions/posts_steps.rb
+++ b/features/step_definitions/posts_steps.rb
@@ -2,3 +2,9 @@ When /^I click share across aspects$/ do
   find("#expand_publisher").click
 end
 
+When /^I post a photo with a token$/ do
+  json = JSON.parse <<JSON
+        {"activity":{"actor":{"url":"http://cubbi.es/daniel","displayName":"daniel","objectType":"person"},"published":"2011-05-19T18:12:23Z","verb":"save","object":{"objectType":"photo","url":"http://i658.photobucket.com/albums/uu308/R3b3lAp3/Swagger_dog.jpg","image":{"url":"http://i658.photobucket.com/albums/uu308/R3b3lAp3/Swagger_dog.jpg","width":637,"height":469}},"provider":{"url":"http://cubbi.es/","displayName":"Cubbi.es"}}}
+JSON
+  page.driver.post(activity_streams_photos_path, json.merge!(:auth_token => @me.authentication_token))
+end
diff --git a/spec/controllers/tokens_controller_spec.rb b/spec/controllers/tokens_controller_spec.rb
index da28cf4011..3a18bdb193 100644
--- a/spec/controllers/tokens_controller_spec.rb
+++ b/spec/controllers/tokens_controller_spec.rb
@@ -1,8 +1,4 @@
 describe TokensController do
-  before do
-    AppConfig[:admins] = [bob.username]
-    AppConfig[:auth_tokenable] = [eve.username]
-  end
   describe '#create' do
     it 'generates a new token for the current user' do
       sign_in bob
@@ -10,18 +6,13 @@ describe TokensController do
         get :create
       }.should change{ bob.reload.authentication_token }
     end
-    it 'redirects normal users away' do
-      sign_in alice
-      get :create
-      response.should redirect_to root_url
-    end
   end
   describe '#edit' do
     it 'displays a token' do
-      sign_in bob
+      sign_in eve
       get :create
       get :show
-      response.body.should include(bob.reload.authentication_token)
+      response.body.should include(eve.reload.authentication_token)
     end
   end
 end
diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb
index 0c29153053..dc99406a8a 100644
--- a/spec/controllers/users_controller_spec.rb
+++ b/spec/controllers/users_controller_spec.rb
@@ -34,7 +34,7 @@ describe UsersController do
     end
 
     it 'redirects to a profile page if html is requested' do
-      
+
       get :public, :username => @user.username
       response.should be_redirect
     end
@@ -137,5 +137,12 @@ describe UsersController do
       get 'edit', :id => @user.id
       assigns[:email_prefs]['mentioned'].should be_false
     end
+
+    it 'does not allow token auth' do
+      sign_out :user
+      bob.reset_authentication_token!
+      get :edit, :auth_token => bob.authentication_token
+      response.should redirect_to new_user_session_path
+    end
   end
 end
-- 
GitLab