From 93bb6a574c29fd0688157f19753b2c50b30aba4d Mon Sep 17 00:00:00 2001 From: Jens Kraemer Date: Mon, 20 May 2019 11:28:02 +0800 Subject: [PATCH] enables API access to /my/account for updating user account data --- app/controllers/my_controller.rb | 18 +++++- app/views/my/account.api.rsb | 13 +++++ config/routes.rb | 2 +- test/integration/api_test/my_test.rb | 106 +++++++++++++++++++++++++++++++++++ 4 files changed, 135 insertions(+), 4 deletions(-) create mode 100644 app/views/my/account.api.rsb create mode 100644 test/integration/api_test/my_test.rb diff --git a/app/controllers/my_controller.rb b/app/controllers/my_controller.rb index 466aeab73..13bdf988a 100644 --- a/app/controllers/my_controller.rb +++ b/app/controllers/my_controller.rb @@ -23,6 +23,8 @@ class MyController < ApplicationController # let user change user's password when user has to skip_before_action :check_password_change, :only => :password + accept_api_auth :account + require_sudo_mode :account, only: :post require_sudo_mode :reset_rss_key, :reset_api_key, :show_api_key, :destroy @@ -49,15 +51,25 @@ class MyController < ApplicationController def account @user = User.current @pref = @user.pref - if request.post? + if request.post? || request.put? @user.safe_attributes = params[:user] @user.pref.safe_attributes = params[:pref] if @user.save @user.pref.save set_language_if_valid @user.language - flash[:notice] = l(:notice_account_updated) - redirect_to my_account_path + respond_to do |format| + format.html { + flash[:notice] = l(:notice_account_updated) + redirect_to my_account_path + } + format.api { render_api_ok } + end return + else + respond_to do |format| + format.html { render :action => :account } + format.api { render_validation_errors(@user) } + end end end end diff --git a/app/views/my/account.api.rsb b/app/views/my/account.api.rsb new file mode 100644 index 000000000..c1cac2bbe --- /dev/null +++ b/app/views/my/account.api.rsb @@ -0,0 +1,13 @@ +api.user do + api.id @user.id + api.login @user.login + api.admin @user.admin? + api.firstname @user.firstname + api.lastname @user.lastname + api.mail @user.mail + api.created_on @user.created_on + api.last_login_on @user.last_login_on + api.api_key @user.api_key + + render_api_custom_values @user.visible_custom_field_values, api +end diff --git a/config/routes.rb b/config/routes.rb index 3c1fd0256..c64626fe0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -72,7 +72,7 @@ Rails.application.routes.draw do match '/imports/:id/mapping', :to => 'imports#mapping', :via => [:get, :post], :as => 'import_mapping' match '/imports/:id/run', :to => 'imports#run', :via => [:get, :post], :as => 'import_run' - match 'my/account', :controller => 'my', :action => 'account', :via => [:get, :post] + match 'my/account', :controller => 'my', :action => 'account', :via => [:get, :post, :put] match 'my/account/destroy', :controller => 'my', :action => 'destroy', :via => [:get, :post] match 'my/page', :controller => 'my', :action => 'page', :via => :get post 'my/page', :to => 'my#update_page' diff --git a/test/integration/api_test/my_test.rb b/test/integration/api_test/my_test.rb new file mode 100644 index 000000000..92a54f3ea --- /dev/null +++ b/test/integration/api_test/my_test.rb @@ -0,0 +1,106 @@ +# frozen_string_literal: true + +# Redmine - project management software +# Copyright (C) 2006-2017 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +require File.expand_path('../../../test_helper', __FILE__) + +class Redmine::ApiTest::MyTest < Redmine::ApiTest::Base + fixtures :users, :email_addresses, :members, :member_roles, :roles, :projects + + test "GET /my/account.json should return user" do + assert Setting.rest_api_enabled? + get '/my/account.json', :headers => credentials('dlopper', 'foo') + + assert_response :success + assert_equal 'application/json', response.content_type + json = ActiveSupport::JSON.decode(response.body) + assert json.key?('user') + assert_equal 'dlopper', json['user']['login'] + end + + test "PUT /my/account.xml with valid parameters should update the user" do + put '/my/account.xml', + :params => { + :user => { + :firstname => 'Dave', :lastname => 'Renamed', + :mail => 'dave@somenet.foo' + } + }, + :headers => credentials('dlopper', 'foo') + assert_response :no_content + assert_equal '', @response.body + + assert user = User.find_by_lastname('Renamed') + assert_equal 'Dave', user.firstname + assert_equal 'Renamed', user.lastname + assert_equal 'dave@somenet.foo', user.mail + refute user.admin? + end + + test "PUT /my/account.json with valid parameters should update the user" do + put '/my/account.xml', + :params => { + :user => { + :firstname => 'Dave', :lastname => 'Renamed', + :mail => 'dave@somenet.foo' + } + }, + :headers => credentials('dlopper', 'foo') + assert_response :no_content + assert_equal '', @response.body + + assert user = User.find_by_lastname('Renamed') + assert_equal 'Dave', user.firstname + assert_equal 'Renamed', user.lastname + assert_equal 'dave@somenet.foo', user.mail + refute user.admin? + + end + + test "PUT /my/account.xml with invalid parameters" do + put '/my/account.xml', + :params => { + :user => { + :login => 'dlopper', :firstname => '', :lastname => 'Lastname' + } + }, + :headers => credentials('dlopper', 'foo') + + assert_response :unprocessable_entity + assert_equal 'application/xml', @response.content_type + assert_select 'errors error', :text => "First name cannot be blank" + end + + test "PUT /my/account.json with invalid parameters" do + put '/my/account.json', + :params => { + :user => { + :login => 'dlopper', :firstname => '', :lastname => 'Lastname' + } + }, + :headers => credentials('dlopper', 'foo') + + assert_response :unprocessable_entity + assert_equal 'application/json', @response.content_type + json = ActiveSupport::JSON.decode(response.body) + assert_kind_of Hash, json + assert json.has_key?('errors') + assert_kind_of Array, json['errors'] + end +end + -- 2.11.0