Merge oauth branch at r17138 to trunk.
authorTom Hughes <tom@compton.nu>
Tue, 18 Aug 2009 20:01:56 +0000 (20:01 +0000)
committerTom Hughes <tom@compton.nu>
Tue, 18 Aug 2009 20:01:56 +0000 (20:01 +0000)
1  2 
app/controllers/application_controller.rb
app/controllers/trace_controller.rb

index 3eefa4a9142d4d760b959799b33fb5fad0803b4a,6dbe9165ca2593b20f5fff3c7e6c46f7469016e6..c43271b93a81faf5b3426a75097ac5fc1053f0e5
@@@ -22,19 -22,61 +22,61 @@@ class ApplicationController < ActionCon
      redirect_to :controller => 'user', :action => 'login', :referer => request.request_uri unless @user
    end
  
+   ##
+   # requires the user to be logged in by the token or HTTP methods, or have an 
+   # OAuth token with the right capability. this method is a bit of a pain to call 
+   # directly, since it's cumbersome to call filters with arguments in rails. to
+   # make it easier to read and write the code, there are some utility methods
+   # below.
+   def require_capability(cap)
+     # when the current token is nil, it means the user logged in with a different
+     # method, otherwise an OAuth token was used, which has to be checked.
+     unless current_token.nil?
+       unless current_token.read_attribute(cap)
+         render :text => "OAuth token doesn't have that capability.", :status => :forbidden
+         return false
+       end
+     end
+   end
+   # Utility methods to make the controller filter methods easier to read and write.
+   def require_allow_read_prefs
+     require_capability(:allow_read_prefs)
+   end
+   def require_allow_write_prefs
+     require_capability(:allow_write_prefs)
+   end
+   def require_allow_write_diary
+     require_capability(:allow_write_diary)
+   end
+   def require_allow_write_api
+     require_capability(:allow_write_api)
+   end
+   def require_allow_read_gpx
+     require_capability(:allow_read_gpx)
+   end
+   def require_allow_write_gpx
+     require_capability(:allow_write_gpx)
+   end
    ##
    # sets up the @user object for use by other methods. this is mostly called
    # from the authorize method, but can be called elsewhere if authorisation
    # is optional.
    def setup_user_auth
-     username, passwd = get_auth_data # parse from headers
-     # authenticate per-scheme
-     if username.nil?
-       @user = nil # no authentication provided - perhaps first connect (client should retry after 401)
-     elsif username == 'token' 
-       @user = User.authenticate(:token => passwd) # preferred - random token for user from db, passed in basic auth
+     # try and setup using OAuth
+     if oauthenticate
+       @user = current_token.user
      else
-       @user = User.authenticate(:username => username, :password => passwd) # basic auth
+       username, passwd = get_auth_data # parse from headers
+       # authenticate per-scheme
+       if username.nil?
+         @user = nil # no authentication provided - perhaps first connect (client should retry after 401)
+       elsif username == 'token'
+         @user = User.authenticate(:token => passwd) # preferred - random token for user from db, passed in basic auth
+       else
+         @user = User.authenticate(:username => username, :password => passwd) # basic auth
+       end
      end
    end
  
      rescue OSM::APIError => ex
        report_error ex.message, ex.status
      rescue Exception => ex
 +      logger.info("API threw unexpected #{ex.class} exception: #{ex.message}")
 +      ex.backtrace.each { |l| logger.info(l) }
        report_error "#{ex.class}: #{ex.message}", :internal_server_error
      end
    end
index 1dee0b9248ee539549e7e5ff898350db28c87b6a,f06a162fbc00b850d03b971cc7a59ae9ad60ec62..10aecd4adc7733e8c2309253bbbed6d5ad2f4b02
@@@ -9,6 -9,8 +9,8 @@@ class TraceController < ApplicationCont
    before_filter :check_database_writable, :only => [:create, :edit, :delete]
    before_filter :check_api_readable, :only => [:api_details, :api_data]
    before_filter :check_api_writable, :only => [:api_create]
+   before_filter :require_allow_read_gpx, :only => [:api_details, :api_data]
+   before_filter :require_allow_write_gpx, :only => [:api_create]
   
    # Counts and selects pages of GPX traces for various criteria (by user, tags, public etc.).
    #  target_user - if set, specifies the user to fetch traces for.  if not set will fetch all traces
      # 4 - user's traces, not logged in as that user = all user's public traces
      if target_user.nil? # all traces
        if @user
 -        conditions = ["(gpx_files.visibility <> 'private' OR gpx_files.user_id = ?)", @user.id] #1
 +        conditions = ["(gpx_files.visibility in ('public', 'identifiable') OR gpx_files.user_id = ?)", @user.id] #1
        else
 -        conditions  = ["gpx_files.visibility <> 'private'"] #2
 +        conditions  = ["gpx_files.visibility in ('public', 'identifiable')"] #2
        end
      else
        if @user and @user == target_user
          conditions = ["gpx_files.user_id = ?", @user.id] #3 (check vs user id, so no join + can't pick up non-public traces by changing name)
        else
 -        conditions = ["gpx_files.public <> 'private' AND gpx_files.user_id = ?", target_user.id] #4
 +        conditions = ["gpx_files.visibility in ('public', 'identifiable') AND gpx_files.user_id = ?", target_user.id] #4
        end
      end
      
    end
  
    def georss
 -    conditions = ["gpx_files.visibility <> 'private'"]
 +    conditions = ["gpx_files.visibility in ('public', 'identifiable')"]
  
      if params[:display_name]
        conditions[0] += " AND users.display_name = ?"