diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index bd309f1a2b0..640ded45786 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -7,7 +7,7 @@ class UsersController < ApplicationController skip_before_filter :authorize_mini_profiler, only: [:avatar] skip_before_filter :check_xhr, only: [:show, :password_reset, :update, :activate_account, :authorize_email, :user_preferences_redirect, :avatar] - before_filter :ensure_logged_in, only: [:username, :update, :change_email, :user_preferences_redirect] + before_filter :ensure_logged_in, only: [:username, :update, :change_email, :user_preferences_redirect, :upload_avatar, :toggle_avatar] # we need to allow account creation with bad CSRF tokens, if people are caching, the CSRF token on the # page is going to be empty, this means that server will see an invalid CSRF and blow the session @@ -346,13 +346,18 @@ class UsersController < ApplicationController upload = Upload.create_for(user.id, file, filesize) + user.uploaded_avatar_template = nil user.uploaded_avatar = upload user.use_uploaded_avatar = true user.save! Jobs.enqueue(:generate_avatars, upload_id: upload.id) - render json: { url: upload.url } + render json: { + url: upload.url, + width: upload.width, + height: upload.height, + } rescue FastImage::ImageFetchFailure render status: 422, text: I18n.t("upload.images.fetch_failure") diff --git a/config/routes.rb b/config/routes.rb index 632ec2db4c4..1ace9838952 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -138,11 +138,9 @@ Discourse::Application.routes.draw do get 'users/:username/preferences/about-me' => 'users#preferences', constraints: {username: USERNAME_ROUTE_FORMAT} get 'users/:username/preferences/username' => 'users#preferences', constraints: {username: USERNAME_ROUTE_FORMAT} put 'users/:username/preferences/username' => 'users#username', constraints: {username: USERNAME_ROUTE_FORMAT} - # LEGACY ROUTE - get 'users/:username/avatar(/:size)' => 'users#avatar', constraints: {username: USERNAME_ROUTE_FORMAT} - get 'users/:username/preferences/avatar' => 'users#preferences', constraints: {username: USERNAME_ROUTE_FORMAT} - put 'users/:username/preferences/avatar/toggle' => 'users#toggle_avatar', constraints: {username: USERNAME_ROUTE_FORMAT} + get 'users/:username/avatar(/:size)' => 'users#avatar', constraints: {username: USERNAME_ROUTE_FORMAT} # LEGACY ROUTE post 'users/:username/preferences/avatar' => 'users#upload_avatar', constraints: {username: USERNAME_ROUTE_FORMAT} + put 'users/:username/preferences/avatar/toggle' => 'users#toggle_avatar', constraints: {username: USERNAME_ROUTE_FORMAT} get 'users/:username/invited' => 'users#invited', constraints: {username: USERNAME_ROUTE_FORMAT} post 'users/:username/send_activation_email' => 'users#send_activation_email', constraints: {username: USERNAME_ROUTE_FORMAT} get 'users/:username/activity' => 'users#show', constraints: {username: USERNAME_ROUTE_FORMAT} diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index ee774d57e97..96308a06853 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -938,4 +938,90 @@ describe UsersController do end end + describe '.upload_avatar' do + + it 'raises an error when not logged in' do + lambda { xhr :put, :upload_avatar, username: 'asdf' }.should raise_error(Discourse::NotLoggedIn) + end + + context 'while logged in' do + + let!(:user) { log_in } + + let(:avatar) do + ActionDispatch::Http::UploadedFile.new({ + filename: 'logo.png', + tempfile: File.new("#{Rails.root}/spec/fixtures/images/logo.png") + }) + end + + it 'raises an error when you don\'t have permission to upload an avatar' do + Guardian.any_instance.expects(:can_edit?).with(user).returns(false) + xhr :post, :upload_avatar, username: user.username + response.should be_forbidden + end + + it 'rejects large images' do + SiteSetting.stubs(:max_image_size_kb).returns(1) + xhr :post, :upload_avatar, username: user.username, file: avatar + response.status.should eq 413 + end + + it 'is successful' do + upload = Fabricate(:upload) + Upload.expects(:create_for).returns(upload) + # enqueues the avatar generator job + Jobs.expects(:enqueue).with(:generate_avatars, { upload_id: upload.id }) + xhr :post, :upload_avatar, username: user.username, file: avatar + user.reload + # erase the previous template + user.uploaded_avatar_template.should == nil + # link to the right upload + user.uploaded_avatar.id.should == upload.id + # automatically set "use_uploaded_avatar" + user.use_uploaded_avatar.should == true + end + + it 'returns the url, width and height of the uploaded image' do + xhr :post, :upload_avatar, username: user.username, file: avatar + json = JSON.parse(response.body) + json['url'].should_not be_nil + json['width'].should == 244 + json['height'].should == 66 + end + + end + + end + + describe '.toggle_avatar' do + + it 'raises an error when not logged in' do + lambda { xhr :put, :toggle_avatar, username: 'asdf' }.should raise_error(Discourse::NotLoggedIn) + end + + context 'while logged in' do + + let!(:user) { log_in } + + it 'raises an error without a use_uploaded_avatar param' do + lambda { xhr :put, :toggle_avatar, username: user.username }.should raise_error(ActionController::ParameterMissing) + end + + it 'raises an error when you don\'t have permission to toggle the avatar' do + Guardian.any_instance.expects(:can_edit?).with(user).returns(false) + xhr :put, :toggle_avatar, username: user.username, use_uploaded_avatar: "true" + response.should be_forbidden + end + + it 'it successful' do + xhr :put, :toggle_avatar, username: user.username, use_uploaded_avatar: "false" + user.reload.use_uploaded_avatar.should == false + response.should be_success + end + + end + + end + end