diff --git a/app/controllers/concerns/access_token_auth_helper.rb b/app/controllers/concerns/access_token_auth_helper.rb index 0a6c89860..cd760f7ce 100644 --- a/app/controllers/concerns/access_token_auth_helper.rb +++ b/app/controllers/concerns/access_token_auth_helper.rb @@ -1,7 +1,8 @@ module AccessTokenAuthHelper BOT_ACCESSIBLE_ENDPOINTS = { - 'api/v1/accounts/conversations' => %w[toggle_status create], - 'api/v1/accounts/conversations/messages' => ['create'] + 'api/v1/accounts/conversations' => %w[toggle_status toggle_priority create], + 'api/v1/accounts/conversations/messages' => ['create'], + 'api/v1/accounts/conversations/assignments' => ['create'] }.freeze def ensure_access_token diff --git a/app/controllers/concerns/ensure_current_account_helper.rb b/app/controllers/concerns/ensure_current_account_helper.rb index 5d02e96c8..3baf9ee1e 100644 --- a/app/controllers/concerns/ensure_current_account_helper.rb +++ b/app/controllers/concerns/ensure_current_account_helper.rb @@ -25,6 +25,6 @@ module EnsureCurrentAccountHelper end def account_accessible_for_bot?(account) - render_unauthorized('You are not authorized to access this account') unless @resource.agent_bot_inboxes.find_by(account_id: account.id) + render_unauthorized('Bot is not authorized to access this account') unless @resource.agent_bot_inboxes.find_by(account_id: account.id) end end diff --git a/spec/controllers/api/v1/accounts/conversations/assignments_controller_spec.rb b/spec/controllers/api/v1/accounts/conversations/assignments_controller_spec.rb index a4e9d8cb0..8ed70b7a2 100644 --- a/spec/controllers/api/v1/accounts/conversations/assignments_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/conversations/assignments_controller_spec.rb @@ -14,6 +14,26 @@ RSpec.describe 'Conversation Assignment API', type: :request do end end + context 'when it is an authenticated bot with out access to the inbox' do + let(:agent_bot) { create(:agent_bot, account: account) } + let(:agent) { create(:user, account: account, role: :agent) } + + before do + create(:inbox_member, inbox: conversation.inbox, user: agent) + end + + it 'returns unauthorized' do + post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/assignments", + headers: { api_access_token: agent_bot.access_token.token }, + params: { + assignee_id: agent.id + }, + as: :json + + expect(response).to have_http_status(:unauthorized) + end + end + context 'when it is an authenticated user with access to the inbox' do let(:agent) { create(:user, account: account, role: :agent) } let(:team) { create(:team, account: account) } @@ -52,6 +72,50 @@ RSpec.describe 'Conversation Assignment API', type: :request do end end + context 'when it is an authenticated bot with access to the inbox' do + let(:agent_bot) { create(:agent_bot, account: account) } + let(:agent) { create(:user, account: account, role: :agent) } + let(:team) { create(:team, account: account) } + + before do + create(:agent_bot_inbox, inbox: conversation.inbox, agent_bot: agent_bot) + end + + it 'assignment of an agent in the conversation by bot agent' do + create(:inbox_member, user: agent, inbox: conversation.inbox) + + conversation.update!(assignee_id: nil) + expect(conversation.reload.assignee).to be_nil + + post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/assignments", + headers: { api_access_token: agent_bot.access_token.token }, + params: { + assignee_id: agent.id + }, + as: :json + + expect(response).to have_http_status(:success) + expect(conversation.reload.assignee).to eq(agent) + end + + it 'assignment of an team in the conversation by bot agent' do + create(:inbox_member, user: agent, inbox: conversation.inbox) + + conversation.update!(team_id: nil) + expect(conversation.reload.team).to be_nil + + post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/assignments", + headers: { api_access_token: agent_bot.access_token.token }, + params: { + team_id: team.id + }, + as: :json + + expect(response).to have_http_status(:success) + expect(conversation.reload.team).to eq(team) + end + end + context 'when conversation already has an assignee' do let(:agent) { create(:user, account: account, role: :agent) } diff --git a/spec/controllers/api/v1/accounts/conversations_controller_spec.rb b/spec/controllers/api/v1/accounts/conversations_controller_spec.rb index 4c4bb9dc9..72e6603f7 100644 --- a/spec/controllers/api/v1/accounts/conversations_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/conversations_controller_spec.rb @@ -466,7 +466,11 @@ RSpec.describe 'Conversations API', type: :request do end describe 'POST /api/v1/accounts/{account.id}/conversations/:id/toggle_priority' do + let(:inbox) { create(:inbox, account: account) } let(:conversation) { create(:conversation, account: account) } + let(:pending_conversation) { create(:conversation, inbox: inbox, account: account, status: 'pending') } + let(:agent) { create(:user, account: account, role: :agent) } + let(:agent_bot) { create(:agent_bot, account: account) } context 'when it is an unauthenticated user' do it 'returns unauthorized' do @@ -477,7 +481,6 @@ RSpec.describe 'Conversations API', type: :request do end context 'when it is an authenticated user' do - let(:agent) { create(:user, account: account, role: :agent) } let(:administrator) { create(:user, account: account, role: :administrator) } before do @@ -509,6 +512,23 @@ RSpec.describe 'Conversations API', type: :request do expect(conversation.reload.priority).to be_nil end end + + context 'when it is an authenticated bot' do + it 'toggle the priority of the bot agent conversation' do + create(:agent_bot_inbox, inbox: inbox, agent_bot: agent_bot) + + conversation.update!(priority: 'low') + expect(conversation.reload.priority).to eq('low') + + post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/toggle_priority", + headers: { api_access_token: agent_bot.access_token.token }, + params: { priority: 'high' }, + as: :json + + expect(response).to have_http_status(:success) + expect(conversation.reload.priority).to eq('high') + end + end end describe 'POST /api/v1/accounts/{account.id}/conversations/:id/toggle_typing_status' do diff --git a/swagger/paths/application/conversation/assignments.yml b/swagger/paths/application/conversation/assignments.yml index a7b001e5c..a67ce59ad 100644 --- a/swagger/paths/application/conversation/assignments.yml +++ b/swagger/paths/application/conversation/assignments.yml @@ -3,6 +3,9 @@ tags: operationId: assign-a-conversation summary: Assign Conversation description: Assign a conversation to an agent or a team +security: + - userApiKey: [] + - agentBotApiKey: [] parameters: - name: data in: body diff --git a/swagger/swagger.json b/swagger/swagger.json index 9bee2c952..4859a785f 100644 --- a/swagger/swagger.json +++ b/swagger/swagger.json @@ -3327,6 +3327,18 @@ "operationId": "assign-a-conversation", "summary": "Assign Conversation", "description": "Assign a conversation to an agent or a team", + "security": [ + { + "userApiKey": [ + + ] + }, + { + "agentBotApiKey": [ + + ] + } + ], "parameters": [ { "name": "data",