From: Tom Hughes Date: Tue, 18 Aug 2009 20:01:56 +0000 (+0000) Subject: Merge oauth branch at r17138 to trunk. X-Git-Tag: live~7786 X-Git-Url: https://git.openstreetmap.org./rails.git/commitdiff_plain/d227589a6336999c38bffc5e11655100b9a4630a?ds=sidebyside;hp=-c Merge oauth branch at r17138 to trunk. --- d227589a6336999c38bffc5e11655100b9a4630a diff --combined app/controllers/application_controller.rb index 3eefa4a91,6dbe9165c..c43271b93 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@@ -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 @@@ -132,8 -174,6 +174,8 @@@ 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 diff --combined app/controllers/trace_controller.rb index 1dee0b924,f06a162fb..10aecd4ad --- a/app/controllers/trace_controller.rb +++ b/app/controllers/trace_controller.rb @@@ -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 @@@ -43,15 -45,15 +45,15 @@@ # 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 @@@ -205,7 -207,7 +207,7 @@@ 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 = ?"