diff --git a/Gemfile b/Gemfile index bf1f2010d4..0bfd9af374 100644 --- a/Gemfile +++ b/Gemfile @@ -14,7 +14,7 @@ gem 'jquery-rails' gem 'rails-i18n', ">= 0.6.3" gem 'dynamic_form' gem 'rinku', '>= 1.2.2', :require => 'rails_rinku' -gem 'oauth-plugin', '>= 0.4.0.1' +gem 'oauth-plugin', :git => 'git://github.com/tomhughes/oauth-plugin.git' # while waiting for release of version 0.4.0.1 gem 'open_id_authentication', '>= 1.1.0' gem 'validates_email_format_of', '>= 1.5.1' gem 'composite_primary_keys', '>= 5.0.0' diff --git a/Gemfile.lock b/Gemfile.lock index c639421584..0e1c11dd15 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,13 @@ +GIT + remote: git://github.com/tomhughes/oauth-plugin.git + revision: 6c929fdc10d00f69743e01c704663f5cdd887a3d + specs: + oauth-plugin (0.4.0) + multi_json + oauth (~> 0.4.4) + oauth2 (>= 0.5.0) + rack + GEM remote: http://rubygems.org/ specs: @@ -72,11 +82,6 @@ GEM multipart-post (1.1.5) nokogiri (1.5.2) oauth (0.4.6) - oauth-plugin (0.4.0.1) - multi_json - oauth (~> 0.4.4) - oauth2 (>= 0.5.0) - rack oauth2 (0.7.0) faraday (~> 0.8) httpauth (~> 0.1) @@ -165,7 +170,7 @@ DEPENDENCIES jquery-rails libxml-ruby (>= 2.0.5) memcached (>= 1.4.1) - oauth-plugin (>= 0.4.0.1) + oauth-plugin! open_id_authentication (>= 1.1.0) paperclip (~> 2.0) pg diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index 002bd73b88..602b79d69c 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -2,6 +2,7 @@ class ApiController < ApplicationController skip_before_filter :verify_authenticity_token before_filter :check_api_readable, :except => [:capabilities] + before_filter :setup_user_auth, :only => [:permissions] after_filter :compress_output around_filter :api_call_handle_error, :api_call_timeout @@ -289,4 +290,20 @@ def capabilities render :text => doc.to_s, :content_type => "text/xml" end + + # External apps that use the api are able to query which permissions + # they have. This currently returns a list of permissions granted to the current user: + # * if authenticated via OAuth, this list will contain all permissions granted by the user to the access_token. + # * if authenticated via basic auth all permissions are granted, so the list will contain all permissions. + # * unauthenticated users have no permissions, so the list will be empty. + def permissions + @permissions = case + when current_token.present? + ClientApplication.all_permissions.select { |p| current_token.read_attribute(p) } + when @user + ClientApplication.all_permissions + else + [] + end + end end diff --git a/app/views/api/permissions.builder b/app/views/api/permissions.builder new file mode 100644 index 0000000000..066f567887 --- /dev/null +++ b/app/views/api/permissions.builder @@ -0,0 +1,9 @@ +# create list of permissions +xml.instruct! :xml, :version=>"1.0" +xml.osm("version" => "#{API_VERSION}", "generator" => "OpenStreetMap Server") do + xml.permissions do + @permissions.each do |permission| + xml.permission :name => permission + end + end +end diff --git a/config/routes.rb b/config/routes.rb index bc4c12c972..c24ba05e31 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,6 +2,7 @@ # API match 'api/capabilities' => 'api#capabilities', :via => :get match 'api/0.6/capabilities' => 'api#capabilities', :via => :get + match 'api/0.6/permissions' => 'api#permissions', :via => :get match 'api/0.6/changeset/create' => 'changeset#create', :via => :put match 'api/0.6/changeset/:id/upload' => 'changeset#upload', :via => :post, :id => /\d+/ diff --git a/test/functional/api_controller_test.rb b/test/functional/api_controller_test.rb index adc433fe07..ae3817f1a2 100644 --- a/test/functional/api_controller_test.rb +++ b/test/functional/api_controller_test.rb @@ -298,4 +298,42 @@ def test_capabilities end end end + + def test_permissions_anonymous + get :permissions + assert_response :success + assert_select "osm > permissions", :count => 1 do + assert_select "permission", :count => 0 + end + end + + def test_permissions_basic_auth + basic_authorization(users(:normal_user).email, "test") + get :permissions + assert_response :success + assert_select "osm > permissions", :count => 1 do + assert_select "permission", :count => ClientApplication.all_permissions.size + ClientApplication.all_permissions.each do |p| + assert_select "permission[name=#{p}]", :count => 1 + end + end + end + + def test_permissions_oauth + @token = AccessToken.new do |token| + # Just to test a few + token.allow_read_prefs = true + token.allow_write_api = true + token.allow_read_gpx = false + end + @request.env["oauth.token"] = @token + get :permissions + assert_response :success + assert_select "osm > permissions", :count => 1 do + assert_select "permission", :count => 2 + assert_select "permission[name=allow_read_prefs]", :count => 1 + assert_select "permission[name=allow_write_api]", :count => 1 + assert_select "permission[name=allow_read_gpx]", :count => 0 + end + end end