feat: Ability to update avatars from super admin (#7264)
- Ability to update user avatars from super admin - Ability to update bot avatars from super admin fixes: #7060
This commit is contained in:
1
Gemfile
1
Gemfile
@@ -75,6 +75,7 @@ gem 'jwt'
|
|||||||
gem 'pundit'
|
gem 'pundit'
|
||||||
# super admin
|
# super admin
|
||||||
gem 'administrate'
|
gem 'administrate'
|
||||||
|
gem 'administrate-field-active_storage'
|
||||||
|
|
||||||
##--- gems for pubsub service ---##
|
##--- gems for pubsub service ---##
|
||||||
# https://karolgalanciak.com/blog/2019/11/30/from-activerecord-callbacks-to-publish-slash-subscribe-pattern-and-event-driven-design/
|
# https://karolgalanciak.com/blog/2019/11/30/from-activerecord-callbacks-to-publish-slash-subscribe-pattern-and-event-driven-design/
|
||||||
|
|||||||
@@ -113,6 +113,9 @@ GEM
|
|||||||
kaminari (>= 1.0)
|
kaminari (>= 1.0)
|
||||||
sassc-rails (~> 2.1)
|
sassc-rails (~> 2.1)
|
||||||
selectize-rails (~> 0.6)
|
selectize-rails (~> 0.6)
|
||||||
|
administrate-field-active_storage (0.4.2)
|
||||||
|
administrate (>= 0.2.2)
|
||||||
|
rails (>= 7.0)
|
||||||
annotate (3.2.0)
|
annotate (3.2.0)
|
||||||
activerecord (>= 3.2, < 8.0)
|
activerecord (>= 3.2, < 8.0)
|
||||||
rake (>= 10.4, < 14.0)
|
rake (>= 10.4, < 14.0)
|
||||||
@@ -798,6 +801,7 @@ DEPENDENCIES
|
|||||||
activerecord-import
|
activerecord-import
|
||||||
acts-as-taggable-on
|
acts-as-taggable-on
|
||||||
administrate
|
administrate
|
||||||
|
administrate-field-active_storage
|
||||||
annotate
|
annotate
|
||||||
attr_extras
|
attr_extras
|
||||||
audited (~> 5.3)
|
audited (~> 5.3)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
//= link_tree ../images
|
//= link_tree ../images
|
||||||
//= link administrate/application.css
|
//= link administrate/application.css
|
||||||
//= link administrate/application.js
|
//= link administrate/application.js
|
||||||
|
//= link administrate-field-active_storage/application.css
|
||||||
//= link dashboardChart.js
|
//= link dashboardChart.js
|
||||||
//= link secretField.js
|
//= link secretField.js
|
||||||
|
|||||||
@@ -41,4 +41,14 @@ class SuperAdmin::AgentBotsController < SuperAdmin::ApplicationController
|
|||||||
|
|
||||||
# See https://administrate-prototype.herokuapp.com/customizing_controller_actions
|
# See https://administrate-prototype.herokuapp.com/customizing_controller_actions
|
||||||
# for more information
|
# for more information
|
||||||
|
|
||||||
|
def destroy_avatar
|
||||||
|
avatar = requested_resource.avatar
|
||||||
|
avatar.purge
|
||||||
|
redirect_back(fallback_location: super_admin_agent_bots_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def scoped_resource
|
||||||
|
resource_class.with_attached_avatar
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -45,6 +45,17 @@ class SuperAdmin::UsersController < SuperAdmin::ApplicationController
|
|||||||
# empty values into nil values. It uses other APIs such as `resource_class`
|
# empty values into nil values. It uses other APIs such as `resource_class`
|
||||||
# and `dashboard`:
|
# and `dashboard`:
|
||||||
#
|
#
|
||||||
|
|
||||||
|
def destroy_avatar
|
||||||
|
avatar = requested_resource.avatar
|
||||||
|
avatar.purge
|
||||||
|
redirect_back(fallback_location: super_admin_users_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def scoped_resource
|
||||||
|
resource_class.with_attached_avatar
|
||||||
|
end
|
||||||
|
|
||||||
def resource_params
|
def resource_params
|
||||||
permitted_params = super
|
permitted_params = super
|
||||||
permitted_params.delete(:password) if permitted_params[:password].blank?
|
permitted_params.delete(:password) if permitted_params[:password].blank?
|
||||||
|
|||||||
@@ -10,6 +10,11 @@ class AgentBotDashboard < Administrate::BaseDashboard
|
|||||||
ATTRIBUTE_TYPES = {
|
ATTRIBUTE_TYPES = {
|
||||||
access_token: Field::HasOne,
|
access_token: Field::HasOne,
|
||||||
avatar_url: AvatarField,
|
avatar_url: AvatarField,
|
||||||
|
avatar: Field::ActiveStorage.with_options(
|
||||||
|
destroy_url: proc do |_namespace, _resource, attachment|
|
||||||
|
[:avatar_super_admin_agent_bot, { attachment_id: attachment.id }]
|
||||||
|
end
|
||||||
|
),
|
||||||
id: Field::Number,
|
id: Field::Number,
|
||||||
name: Field::String,
|
name: Field::String,
|
||||||
account: Field::BelongsTo.with_options(searchable: true, searchable_field: 'name', order: 'id DESC'),
|
account: Field::BelongsTo.with_options(searchable: true, searchable_field: 'name', order: 'id DESC'),
|
||||||
@@ -36,6 +41,7 @@ class AgentBotDashboard < Administrate::BaseDashboard
|
|||||||
# an array of attributes that will be displayed on the model's show page.
|
# an array of attributes that will be displayed on the model's show page.
|
||||||
SHOW_PAGE_ATTRIBUTES = %i[
|
SHOW_PAGE_ATTRIBUTES = %i[
|
||||||
id
|
id
|
||||||
|
avatar_url
|
||||||
account
|
account
|
||||||
name
|
name
|
||||||
description
|
description
|
||||||
@@ -47,6 +53,7 @@ class AgentBotDashboard < Administrate::BaseDashboard
|
|||||||
# on the model's form (`new` and `edit`) pages.
|
# on the model's form (`new` and `edit`) pages.
|
||||||
FORM_ATTRIBUTES = %i[
|
FORM_ATTRIBUTES = %i[
|
||||||
name
|
name
|
||||||
|
avatar
|
||||||
account
|
account
|
||||||
description
|
description
|
||||||
outgoing_url
|
outgoing_url
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ class UserDashboard < Administrate::BaseDashboard
|
|||||||
account_users: Field::HasMany,
|
account_users: Field::HasMany,
|
||||||
id: Field::Number,
|
id: Field::Number,
|
||||||
avatar_url: AvatarField,
|
avatar_url: AvatarField,
|
||||||
|
avatar: Field::ActiveStorage.with_options(
|
||||||
|
destroy_url: proc do |_namespace, _resource, attachment|
|
||||||
|
[:avatar_super_admin_user, { attachment_id: attachment.id }]
|
||||||
|
end
|
||||||
|
),
|
||||||
provider: Field::String,
|
provider: Field::String,
|
||||||
uid: Field::String,
|
uid: Field::String,
|
||||||
password: Field::Password,
|
password: Field::Password,
|
||||||
@@ -69,6 +74,7 @@ class UserDashboard < Administrate::BaseDashboard
|
|||||||
# on the model's form (`new` and `edit`) pages.
|
# on the model's form (`new` and `edit`) pages.
|
||||||
FORM_ATTRIBUTES = %i[
|
FORM_ATTRIBUTES = %i[
|
||||||
name
|
name
|
||||||
|
avatar
|
||||||
display_name
|
display_name
|
||||||
email
|
email
|
||||||
password
|
password
|
||||||
|
|||||||
@@ -399,10 +399,15 @@ Rails.application.routes.draw do
|
|||||||
post :seed, on: :member
|
post :seed, on: :member
|
||||||
post :reset_cache, on: :member
|
post :reset_cache, on: :member
|
||||||
end
|
end
|
||||||
resources :users, only: [:index, :new, :create, :show, :edit, :update, :destroy]
|
resources :users, only: [:index, :new, :create, :show, :edit, :update, :destroy] do
|
||||||
|
delete :avatar, on: :member, action: :destroy_avatar
|
||||||
|
end
|
||||||
|
|
||||||
resources :access_tokens, only: [:index, :show]
|
resources :access_tokens, only: [:index, :show]
|
||||||
resources :installation_configs, only: [:index, :new, :create, :show, :edit, :update]
|
resources :installation_configs, only: [:index, :new, :create, :show, :edit, :update]
|
||||||
resources :agent_bots, only: [:index, :new, :create, :show, :edit, :update]
|
resources :agent_bots, only: [:index, :new, :create, :show, :edit, :update] do
|
||||||
|
delete :avatar, on: :member, action: :destroy_avatar
|
||||||
|
end
|
||||||
resources :platform_apps, only: [:index, :new, :create, :show, :edit, :update]
|
resources :platform_apps, only: [:index, :new, :create, :show, :edit, :update]
|
||||||
resource :instance_status, only: [:show]
|
resource :instance_status, only: [:show]
|
||||||
|
|
||||||
|
|||||||
@@ -22,4 +22,25 @@ RSpec.describe 'Super Admin agent-bots API', type: :request do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'DELETE /super_admin/agent_bots/:id/destroy_avatar' do
|
||||||
|
let!(:agent_bot) { create(:agent_bot, :with_avatar) }
|
||||||
|
|
||||||
|
context 'when it is an unauthenticated super admin' do
|
||||||
|
it 'returns unauthorized' do
|
||||||
|
delete "/super_admin/agent_bots/#{agent_bot.id}/avatar", params: { attachment_id: agent_bot.avatar.id }
|
||||||
|
expect(response).to have_http_status(:redirect)
|
||||||
|
expect(agent_bot.reload.avatar).to be_attached
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when it is an authenticated super admin' do
|
||||||
|
it 'destroys the avatar' do
|
||||||
|
sign_in(super_admin, scope: :super_admin)
|
||||||
|
delete "/super_admin/agent_bots/#{agent_bot.id}/avatar", params: { attachment_id: agent_bot.avatar.id }
|
||||||
|
expect(response).to have_http_status(:redirect)
|
||||||
|
expect(agent_bot.reload.avatar).not_to be_attached
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -45,4 +45,25 @@ RSpec.describe 'Super Admin Users API', type: :request do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'DELETE /super_admin/users/:id/avatar' do
|
||||||
|
let!(:user) { create(:user, :with_avatar) }
|
||||||
|
|
||||||
|
context 'when it is an unauthenticated super admin' do
|
||||||
|
it 'returns unauthorized' do
|
||||||
|
delete "/super_admin/users/#{user.id}/avatar", params: { attachment_id: user.avatar.id }
|
||||||
|
expect(response).to have_http_status(:redirect)
|
||||||
|
expect(user.reload.avatar).to be_attached
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when it is an authenticated super admin' do
|
||||||
|
it 'destroys the avatar' do
|
||||||
|
sign_in(super_admin, scope: :super_admin)
|
||||||
|
delete "/super_admin/users/#{user.id}/avatar", params: { attachment_id: user.avatar.id }
|
||||||
|
expect(response).to have_http_status(:redirect)
|
||||||
|
expect(user.reload.avatar).not_to be_attached
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -9,5 +9,9 @@ FactoryBot.define do
|
|||||||
trait :skip_validate do
|
trait :skip_validate do
|
||||||
to_create { |instance| instance.save(validate: false) }
|
to_create { |instance| instance.save(validate: false) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
trait :with_avatar do
|
||||||
|
avatar { fixture_file_upload(Rails.root.join('spec/assets/avatar.png'), 'image/png') }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ FactoryBot.define do
|
|||||||
end
|
end
|
||||||
|
|
||||||
trait :with_avatar do
|
trait :with_avatar do
|
||||||
avatar { Rack::Test::UploadedFile.new('spec/assets/avatar.png', 'image/png') }
|
avatar { fixture_file_upload(Rails.root.join('spec/assets/avatar.png'), 'image/png') }
|
||||||
end
|
end
|
||||||
|
|
||||||
trait :administrator do
|
trait :administrator do
|
||||||
|
|||||||
Reference in New Issue
Block a user