feat: Ability to access user tokens via Platform API (#11537)
- Add Platform API for generating user tokens - Add the swagger documentation. --------- Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com> Co-authored-by: Pranav <pranav@chatwoot.com>
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
class Platform::Api::V1::UsersController < PlatformController
|
class Platform::Api::V1::UsersController < PlatformController
|
||||||
# ref: https://stackoverflow.com/a/45190318/939299
|
# ref: https://stackoverflow.com/a/45190318/939299
|
||||||
# set resource is called for other actions already in platform controller
|
# set resource is called for other actions already in platform controller
|
||||||
# we want to add login to that chain as well
|
# we want to add login and token to that chain as well
|
||||||
before_action(only: [:login]) { set_resource }
|
before_action(only: [:login, :token]) { set_resource }
|
||||||
before_action(only: [:login]) { validate_platform_app_permissible }
|
before_action(only: [:login, :token]) { validate_platform_app_permissible }
|
||||||
|
|
||||||
def show; end
|
def show; end
|
||||||
|
|
||||||
@@ -18,6 +18,8 @@ class Platform::Api::V1::UsersController < PlatformController
|
|||||||
render json: { url: @resource.generate_sso_link }
|
render json: { url: @resource.generate_sso_link }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def token; end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@resource.assign_attributes(user_update_params)
|
@resource.assign_attributes(user_update_params)
|
||||||
|
|
||||||
|
|||||||
9
app/views/platform/api/v1/users/token.json.jbuilder
Normal file
9
app/views/platform/api/v1/users/token.json.jbuilder
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
json.access_token @resource.access_token.token
|
||||||
|
json.expiry nil
|
||||||
|
json.user do
|
||||||
|
json.id @resource.id
|
||||||
|
json.name @resource.name
|
||||||
|
json.display_name @resource.display_name
|
||||||
|
json.email @resource.email
|
||||||
|
json.pubsub_token @resource.pubsub_token
|
||||||
|
end
|
||||||
@@ -396,6 +396,7 @@ Rails.application.routes.draw do
|
|||||||
resources :users, only: [:create, :show, :update, :destroy] do
|
resources :users, only: [:create, :show, :update, :destroy] do
|
||||||
member do
|
member do
|
||||||
get :login
|
get :login
|
||||||
|
post :token
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
resources :agent_bots, only: [:index, :create, :show, :update, :destroy] do
|
resources :agent_bots, only: [:index, :create, :show, :update, :destroy] do
|
||||||
|
|||||||
@@ -76,6 +76,54 @@ RSpec.describe 'Platform Users API', type: :request do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'POST /platform/api/v1/users/{user_id}/token' do
|
||||||
|
context 'when it is an unauthenticated platform app' do
|
||||||
|
it 'returns unauthorized' do
|
||||||
|
post "/platform/api/v1/users/#{user.id}/token"
|
||||||
|
expect(response).to have_http_status(:unauthorized)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when it is an invalid platform app token' do
|
||||||
|
it 'returns unauthorized' do
|
||||||
|
post "/platform/api/v1/users/#{user.id}/token", headers: { api_access_token: 'invalid' }, as: :json
|
||||||
|
expect(response).to have_http_status(:unauthorized)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when it is an authenticated platform app' do
|
||||||
|
let(:platform_app) { create(:platform_app) }
|
||||||
|
|
||||||
|
it 'returns unauthorized when its not a permissible object' do
|
||||||
|
post "/platform/api/v1/users/#{user.id}/token", headers: { api_access_token: platform_app.access_token.token }, as: :json
|
||||||
|
expect(response).to have_http_status(:unauthorized)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns access token for the user with expiry and user info' do
|
||||||
|
create(:platform_app_permissible, platform_app: platform_app, permissible: user)
|
||||||
|
|
||||||
|
post "/platform/api/v1/users/#{user.id}/token",
|
||||||
|
headers: { api_access_token: platform_app.access_token.token }, as: :json
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
data = response.parsed_body
|
||||||
|
|
||||||
|
# Check access token and expiry
|
||||||
|
expect(data['access_token']).to eq(user.access_token.token)
|
||||||
|
expect(data['expiry']).to be_nil
|
||||||
|
|
||||||
|
# Check user info
|
||||||
|
expect(data['user']).to include(
|
||||||
|
'id' => user.id,
|
||||||
|
'name' => user.name,
|
||||||
|
'display_name' => user.display_name,
|
||||||
|
'email' => user.email,
|
||||||
|
'pubsub_token' => user.pubsub_token
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe 'POST /platform/api/v1/users/' do
|
describe 'POST /platform/api/v1/users/' do
|
||||||
context 'when it is an unauthenticated platform app' do
|
context 'when it is an unauthenticated platform app' do
|
||||||
it 'returns unauthorized' do
|
it 'returns unauthorized' do
|
||||||
|
|||||||
@@ -64,6 +64,11 @@
|
|||||||
- $ref: '#/parameters/platform_user_id'
|
- $ref: '#/parameters/platform_user_id'
|
||||||
get:
|
get:
|
||||||
$ref: './platform/users/login.yml'
|
$ref: './platform/users/login.yml'
|
||||||
|
/platform/api/v1/users/{id}/token:
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/parameters/platform_user_id'
|
||||||
|
post:
|
||||||
|
$ref: './platform/users/token.yml'
|
||||||
|
|
||||||
|
|
||||||
# ---------------- end of platform path -----------#
|
# ---------------- end of platform path -----------#
|
||||||
|
|||||||
42
swagger/paths/platform/users/token.yml
Normal file
42
swagger/paths/platform/users/token.yml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
tags:
|
||||||
|
- Users
|
||||||
|
operationId: post-user-token
|
||||||
|
summary: Get User Access Token
|
||||||
|
description: Get the access token of a user
|
||||||
|
security:
|
||||||
|
- platformAppApiKey: []
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Success
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
access_token:
|
||||||
|
type: string
|
||||||
|
description: Access token of the user
|
||||||
|
expiry:
|
||||||
|
type: [integer, "null"]
|
||||||
|
description: Expiry timestamp
|
||||||
|
user:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
description: User ID
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
description: User's full name
|
||||||
|
display_name:
|
||||||
|
type: string
|
||||||
|
description: User's display name
|
||||||
|
email:
|
||||||
|
type: string
|
||||||
|
description: User's email address
|
||||||
|
pubsub_token:
|
||||||
|
type: string
|
||||||
|
description: User's pubsub token
|
||||||
|
401:
|
||||||
|
description: Unauthorized
|
||||||
|
404:
|
||||||
|
description: The given user does not exist
|
||||||
|
|
||||||
@@ -655,6 +655,78 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/platform/api/v1/users/{id}/token": {
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/platform_user_id"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Users"
|
||||||
|
],
|
||||||
|
"operationId": "post-user-token",
|
||||||
|
"summary": "Get User Access Token",
|
||||||
|
"description": "Get the access token of a user",
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"platformAppApiKey": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Success",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"access_token": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Access token of the user"
|
||||||
|
},
|
||||||
|
"expiry": {
|
||||||
|
"type": [
|
||||||
|
"integer",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"description": "Expiry timestamp"
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "User ID"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "User's full name"
|
||||||
|
},
|
||||||
|
"display_name": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "User's display name"
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "User's email address"
|
||||||
|
},
|
||||||
|
"pubsub_token": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "User's pubsub token"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized"
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "The given user does not exist"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/public/api/v1/inboxes/{inbox_identifier}": {
|
"/public/api/v1/inboxes/{inbox_identifier}": {
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user