# frozen_string_literal: true require 'swagger_helper' RSpec.describe 'users' do let(:'Api-Key') { Fabricate(:api_key).key } let(:'Api-Username') { 'system' } let(:admin) { Fabricate(:admin) } before do SiteSetting.tagging_enabled = true Jobs.run_immediately! sign_in(admin) end path '/users.json' do post 'Creates a user' do tags 'Users' operationId 'createUser' consumes 'application/json' # This endpoint requires an api key or the active param is ignored parameter name: 'Api-Key', in: :header, type: :string, required: true parameter name: 'Api-Username', in: :header, type: :string, required: true expected_request_schema = load_spec_schema('user_create_request') parameter name: :params, in: :body, schema: expected_request_schema produces 'application/json' response '200', 'user created' do expected_response_schema = load_spec_schema('user_create_response') schema expected_response_schema let(:params) { { 'name' => 'user', 'username' => 'user1', 'email' => 'user1@example.com', 'password' => '13498428e9597cab689b468ebc0a5d33', 'active' => true, } } it_behaves_like "a JSON endpoint", 200 do let(:expected_response_schema) { expected_response_schema } let(:expected_request_schema) { expected_request_schema } end end end end path '/u/{username}.json' do get 'Get a single user by username' do tags 'Users' operationId 'getUser' consumes 'application/json' parameter name: 'Api-Key', in: :header, type: :string, required: true parameter name: 'Api-Username', in: :header, type: :string, required: true parameter name: :username, in: :path, type: :string, required: true expected_request_schema = nil produces 'application/json' response '200', 'user response' do expected_response_schema = load_spec_schema('user_get_response') schema expected_response_schema let(:username) { Fabricate(:user).username } it_behaves_like "a JSON endpoint", 200 do let(:expected_response_schema) { expected_response_schema } let(:expected_request_schema) { expected_request_schema } end end end put 'Update a user' do tags 'Users' operationId 'updateUser' consumes 'application/json' parameter name: 'Api-Key', in: :header, type: :string, required: true parameter name: 'Api-Username', in: :header, type: :string, required: true expected_request_schema = load_spec_schema('user_update_request') parameter name: :username, in: :path, type: :string, required: true parameter name: :params, in: :body, schema: expected_request_schema produces 'application/json' response '200', 'user updated' do expected_response_schema = load_spec_schema('user_update_response') schema expected_response_schema let(:username) { Fabricate(:user).username } let(:params) { { 'name' => 'user' } } it_behaves_like "a JSON endpoint", 200 do let(:expected_response_schema) { expected_response_schema } let(:expected_request_schema) { expected_request_schema } end end end end path '/u/by-external/{external_id}.json' do get 'Get a user by external_id' do tags 'Users' operationId 'getUserExternalId' consumes 'application/json' parameter name: 'Api-Key', in: :header, type: :string, required: true parameter name: 'Api-Username', in: :header, type: :string, required: true parameter name: :external_id, in: :path, type: :string, required: true expected_request_schema = nil produces 'application/json' response '200', 'user response' do expected_response_schema = load_spec_schema('user_get_response') schema expected_response_schema let(:user) { Fabricate(:user) } let(:external_id) { '1' } before do SiteSetting.discourse_connect_url = 'http://someurl.com' SiteSetting.enable_discourse_connect = true user.create_single_sign_on_record(external_id: '1', last_payload: '') end it_behaves_like "a JSON endpoint", 200 do let(:expected_response_schema) { expected_response_schema } let(:expected_request_schema) { expected_request_schema } end end end end path '/u/by-external/{provider}/{external_id}.json' do get 'Get a user by identity provider external ID' do tags 'Users' operationId 'getUserIdentiyProviderExternalId' consumes 'application/json' parameter name: 'Api-Key', in: :header, type: :string, required: true parameter name: 'Api-Username', in: :header, type: :string, required: true parameter name: :provider, in: :path, type: :string, required: true, description: "Authentication provider name. Can be found in the provider callback URL: `/auth/{provider}/callback`" parameter name: :external_id, in: :path, type: :string, required: true expected_request_schema = nil produces 'application/json' response '200', 'user response' do expected_response_schema = load_spec_schema('user_get_response') schema expected_response_schema let(:user) { Fabricate(:user) } let(:provider) { 'google_oauth2' } let(:external_id) { 'myuid' } before do SiteSetting.enable_google_oauth2_logins = true UserAssociatedAccount.create!(user: user, provider_uid: 'myuid', provider_name: 'google_oauth2') end it_behaves_like "a JSON endpoint", 200 do let(:expected_response_schema) { expected_response_schema } let(:expected_request_schema) { expected_request_schema } end end end end path '/u/{username}/preferences/avatar/pick.json' do put 'Update avatar' do tags 'Users' operationId 'updateAvatar' consumes 'application/json' expected_request_schema = load_spec_schema('user_update_avatar_request') parameter name: :username, in: :path, type: :string, required: true parameter name: :params, in: :body, schema: expected_request_schema produces 'application/json' response '200', 'avatar updated' do expected_response_schema = load_spec_schema('success_ok_response') let(:user) { Fabricate(:user) } let(:username) { user.username } let(:upload) { Fabricate(:upload, user: user) } let(:params) { { 'upload_id' => upload.id, 'type' => 'uploaded' } } schema(expected_response_schema) it_behaves_like "a JSON endpoint", 200 do let(:expected_response_schema) { expected_response_schema } let(:expected_request_schema) { expected_request_schema } end end end end path '/u/{username}/preferences/email.json' do put 'Update email' do tags 'Users' operationId 'updateEmail' consumes 'application/json' expected_request_schema = load_spec_schema('user_update_email_request') parameter name: :username, in: :path, type: :string, required: true parameter name: :params, in: :body, schema: expected_request_schema produces 'application/json' response '200', 'email updated' do let(:user) { Fabricate(:user) } let(:username) { user.username } let(:params) { { 'email' => "test@example.com" } } expected_response_schema = nil it_behaves_like "a JSON endpoint", 200 do let(:expected_response_schema) { expected_response_schema } let(:expected_request_schema) { expected_request_schema } end end end end path '/u/{username}/preferences/username.json' do put 'Update username' do tags 'Users' operationId 'updateUsername' consumes 'application/json' expected_request_schema = load_spec_schema('user_update_username_request') parameter name: :username, in: :path, type: :string, required: true parameter name: :params, in: :body, schema: expected_request_schema produces 'application/json' response '200', 'username updated' do let(:user) { Fabricate(:user) } let(:username) { user.username } let(:params) { { 'new_username' => "#{user.username}1" } } expected_response_schema = nil it_behaves_like "a JSON endpoint", 200 do let(:expected_response_schema) { expected_response_schema } let(:expected_request_schema) { expected_request_schema } end end end end path '/directory_items.json' do get 'Get a public list of users' do tags 'Users' operationId 'listUsersPublic' consumes 'application/json' expected_request_schema = nil parameter name: :period, in: :query, schema: { type: :string, enum: ['daily', 'weekly', 'monthly', 'quarterly', 'yearly', 'all'] }, required: true parameter name: :order, in: :query, schema: { type: :string, enum: [ 'likes_received', 'likes_given', 'topic_count', 'post_count', 'topics_entered', 'posts_read', 'days_visited' ] }, required: true parameter name: :asc, in: :query, schema: { type: :string, enum: ['true'] } parameter name: :page, in: :query, type: :integer produces 'application/json' response '200', 'directory items response' do let(:period) { 'weekly' } let(:order) { 'likes_received' } let(:asc) { 'true' } let(:page) { 0 } expected_response_schema = load_spec_schema('users_public_list_response') schema(expected_response_schema) it_behaves_like "a JSON endpoint", 200 do let(:expected_response_schema) { expected_response_schema } let(:expected_request_schema) { expected_request_schema } end end end end path '/admin/users/{id}.json' do get 'Get a user by id' do tags 'Users', 'Admin' operationId 'adminGetUser' consumes 'application/json' expected_request_schema = nil parameter name: :id, in: :path, type: :integer, required: true produces 'application/json' response '200', 'response' do let(:id) { Fabricate(:user).id } expected_response_schema = load_spec_schema('admin_user_response') schema(expected_response_schema) it_behaves_like "a JSON endpoint", 200 do let(:expected_response_schema) { expected_response_schema } let(:expected_request_schema) { expected_request_schema } end end end delete 'Delete a user' do tags 'Users', 'Admin' operationId 'deleteUser' consumes 'application/json' expected_request_schema = load_spec_schema('user_delete_request') parameter name: :id, in: :path, type: :integer, required: true parameter name: :params, in: :body, schema: expected_request_schema produces 'application/json' response '200', 'response' do let(:id) { Fabricate(:user).id } let(:params) { { 'delete_posts' => true, 'block_email' => false, 'block_urls' => false, 'block_ip' => false } } expected_response_schema = load_spec_schema('user_delete_response') schema(expected_response_schema) it_behaves_like "a JSON endpoint", 200 do let(:expected_response_schema) { expected_response_schema } let(:expected_request_schema) { expected_request_schema } end end end end path '/admin/users/{id}/suspend.json' do put 'Suspend a user' do tags 'Users', 'Admin' operationId 'suspendUser' consumes 'application/json' expected_request_schema = load_spec_schema('user_suspend_request') parameter name: :id, in: :path, type: :integer, required: true parameter name: :params, in: :body, schema: expected_request_schema produces 'application/json' response '200', 'response' do let(:id) { Fabricate(:user).id } let(:params) { { 'suspend_until' => '2121-02-22', 'reason' => 'inactivity' } } expected_response_schema = load_spec_schema('user_suspend_response') schema(expected_response_schema) it_behaves_like "a JSON endpoint", 200 do let(:expected_response_schema) { expected_response_schema } let(:expected_request_schema) { expected_request_schema } end end end end path '/admin/users/{id}/silence.json' do put 'Silence a user' do tags 'Users', 'Admin' operationId 'silenceUser' consumes 'application/json' expected_request_schema = load_spec_schema('user_silence_request') parameter name: :id, in: :path, type: :integer, required: true parameter name: :params, in: :body, schema: expected_request_schema produces 'application/json' response '200', 'response' do let(:id) { Fabricate(:user).id } let(:params) {} expected_response_schema = load_spec_schema('user_silence_response') schema(expected_response_schema) it_behaves_like "a JSON endpoint", 200 do let(:expected_response_schema) { expected_response_schema } let(:expected_request_schema) { expected_request_schema } end end end end path '/admin/users/{id}/anonymize.json' do put 'Anonymize a user' do tags 'Users', 'Admin' operationId 'anonymizeUser' consumes 'application/json' expected_request_schema = nil parameter name: :id, in: :path, type: :integer, required: true produces 'application/json' response '200', 'response' do let(:id) { Fabricate(:user).id } expected_response_schema = load_spec_schema('user_anonymize_response') schema(expected_response_schema) it_behaves_like "a JSON endpoint", 200 do let(:expected_response_schema) { expected_response_schema } let(:expected_request_schema) { expected_request_schema } end end end end path '/admin/users/{id}/log_out.json' do post 'Log a user out' do tags 'Users', 'Admin' operationId 'logOutUser' consumes 'application/json' expected_request_schema = nil parameter name: :id, in: :path, type: :integer, required: true produces 'application/json' response '200', 'response' do let(:id) { Fabricate(:user).id } expected_response_schema = load_spec_schema('success_ok_response') schema(expected_response_schema) it_behaves_like "a JSON endpoint", 200 do let(:expected_response_schema) { expected_response_schema } let(:expected_request_schema) { expected_request_schema } end end end end path '/user_avatar/{username}/refresh_gravatar.json' do before do stub_request(:get, /https:\/\/www.gravatar.com\/avatar\/\w+.png\?d=404&reset_cache=\S+&s=360/). with( headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip', 'Host' => 'www.gravatar.com' }). to_return(status: 200, body: "", headers: {}) end post 'Refresh gravatar' do tags 'Users', 'Admin' operationId 'refreshGravatar' consumes 'application/json' expected_request_schema = nil parameter name: :username, in: :path, type: :string, required: true produces 'application/json' response '200', 'response' do let(:user) { Fabricate(:user) } let(:username) { user.username } expected_response_schema = load_spec_schema('user_refresh_gravatar_response') schema(expected_response_schema) it_behaves_like "a JSON endpoint", 200 do let(:expected_response_schema) { expected_response_schema } let(:expected_request_schema) { expected_request_schema } end end end end path '/admin/users/list/{flag}.json' do get 'Get a list of users' do tags 'Users', 'Admin' operationId 'adminListUsers' consumes 'application/json' expected_request_schema = nil parameter name: :flag, in: :path, schema: { type: :string, enum: ['active', 'new', 'staff', 'suspended', 'blocked', 'suspect'] }, required: true parameter name: :order, in: :query, schema: { type: :string, enum: [ 'created', 'last_emailed', 'seen', 'username', 'email', 'trust_level', 'days_visited', 'posts_read', 'topics_viewed', 'posts', 'read_time' ] } parameter name: :asc, in: :query, schema: { type: :string, enum: ['true'] } parameter name: :page, in: :query, type: :integer parameter name: :show_emails, in: :query, type: :boolean produces 'application/json' response '200', 'response' do let(:flag) { 'active' } let(:order) { 'created' } let(:asc) { 'true' } let(:page) { 0 } let(:show_emails) { false } expected_response_schema = load_spec_schema('admin_user_list_response') schema(expected_response_schema) it_behaves_like "a JSON endpoint", 200 do let(:expected_response_schema) { expected_response_schema } let(:expected_request_schema) { expected_request_schema } end end end end path '/user_actions.json' do get 'Get a list of user actions' do tags 'Users' operationId 'listUserActions' consumes 'application/json' expected_request_schema = nil parameter name: :offset, in: :query, type: :integer, required: true parameter name: :username, in: :query, type: :string, required: true parameter name: :filter, in: :query, type: :string, required: true produces 'application/json' response '200', 'response' do let(:offset) { 0 } let(:username) { Fabricate(:user).username } let(:filter) { '4,5' } expected_response_schema = load_spec_schema('user_actions_response') schema(expected_response_schema) it_behaves_like "a JSON endpoint", 200 do let(:expected_response_schema) { expected_response_schema } let(:expected_request_schema) { expected_request_schema } end end end end path '/session/forgot_password.json' do post 'Send password reset email' do tags 'Users' operationId 'sendPasswordResetEmail' consumes 'application/json' expected_request_schema = load_spec_schema('user_password_reset_request') parameter name: :params, in: :body, schema: expected_request_schema produces 'application/json' response '200', 'success response' do expected_response_schema = load_spec_schema('user_password_reset_response') schema expected_response_schema let(:user) { Fabricate(:user) } let(:params) { { 'login' => user.username } } it_behaves_like "a JSON endpoint", 200 do let(:expected_response_schema) { expected_response_schema } let(:expected_request_schema) { expected_request_schema } end end end end path '/users/password-reset/{token}.json' do put 'Change password' do tags 'Users' operationId 'changePassword' consumes 'application/json' expected_request_schema = load_spec_schema('user_password_change_request') parameter name: :token, in: :path, type: :string, required: true parameter name: :params, in: :body, schema: expected_request_schema produces 'application/json' response '200', 'success response' do expected_response_schema = nil let(:user) { Fabricate(:user) } let(:token) { Fabricate(:email_token, user: user, scope: EmailToken.scopes[:password_reset]).token } let(:params) do { 'username' => user.username, 'password' => 'NH8QYbxYS5Zv5qEFzA4jULvM' } end it_behaves_like "a JSON endpoint", 200 do let(:expected_response_schema) { expected_response_schema } let(:expected_request_schema) { expected_request_schema } end end end end path '/u/{username}/emails.json' do get 'Get email addresses belonging to a user' do tags 'Users' operationId 'getUserEmails' consumes 'application/json' expected_request_schema = nil parameter name: :username, in: :path, type: :string, required: true produces 'application/json' response '200', 'success response' do expected_response_schema = load_spec_schema('user_emails_response') schema expected_response_schema let(:username) { Fabricate(:user).username } it_behaves_like "a JSON endpoint", 200 do let(:expected_response_schema) { expected_response_schema } let(:expected_request_schema) { expected_request_schema } end end end end end