Custom attribute definitions can now only be created, edited, or deleted by administrators, matching the existing settings UI restriction. Previously, an agent could call the `custom_attribute_definitions` API directly and modify account configuration that they couldn't reach through the dashboard — a Broken Access Control vulnerability reported externally. Fixes https://linear.app/chatwoot/issue/CW-7038/broken-access-control-on-custom-attribute-definitions-api ## How to test 1. Sign in as an agent. 2. Try to create a custom attribute by calling `POST /api/v1/accounts/<id>/custom_attribute_definitions` directly (the settings page is hidden for agents — use curl with the agent's `api_access_token`). 3. Expect `401 Unauthorized` with body `{"error":"You are not authorized to do this action"}`. Repeat for `PATCH` and `DELETE`. 4. Sign in as an administrator and confirm create/edit/delete still work from Settings → Custom Attributes. 5. As either role, the listing endpoint (`GET .../custom_attribute_definitions`) should still succeed — agents need this to render attributes in conversation and contact panels. Co-authored-by: Muhsin <12408980+muhsin-k@users.noreply.github.com>
53 lines
1.4 KiB
Ruby
53 lines
1.4 KiB
Ruby
class Api::V1::Accounts::CustomAttributeDefinitionsController < Api::V1::Accounts::BaseController
|
|
before_action :fetch_custom_attributes_definitions, except: [:create]
|
|
before_action :fetch_custom_attribute_definition, only: [:show, :update, :destroy]
|
|
before_action :check_authorization
|
|
DEFAULT_ATTRIBUTE_MODEL = 'conversation_attribute'.freeze
|
|
|
|
def index; end
|
|
|
|
def show; end
|
|
|
|
def create
|
|
@custom_attribute_definition = Current.account.custom_attribute_definitions.create!(
|
|
permitted_payload
|
|
)
|
|
end
|
|
|
|
def update
|
|
@custom_attribute_definition.update!(permitted_payload)
|
|
end
|
|
|
|
def destroy
|
|
@custom_attribute_definition.destroy!
|
|
head :no_content
|
|
end
|
|
|
|
private
|
|
|
|
def fetch_custom_attributes_definitions
|
|
@custom_attribute_definitions = Current.account.custom_attribute_definitions.with_attribute_model(permitted_params[:attribute_model])
|
|
end
|
|
|
|
def fetch_custom_attribute_definition
|
|
@custom_attribute_definition = Current.account.custom_attribute_definitions.find(permitted_params[:id])
|
|
end
|
|
|
|
def permitted_payload
|
|
params.require(:custom_attribute_definition).permit(
|
|
:attribute_display_name,
|
|
:attribute_description,
|
|
:attribute_display_type,
|
|
:attribute_key,
|
|
:attribute_model,
|
|
:regex_pattern,
|
|
:regex_cue,
|
|
attribute_values: []
|
|
)
|
|
end
|
|
|
|
def permitted_params
|
|
params.permit(:id, :filter_type, :attribute_model)
|
|
end
|
|
end
|