Maintenance: Refactoring of Avatar storage logic.
This commit is contained in:
parent
008053f730
commit
678161be2e
3 changed files with 77 additions and 11 deletions
|
@ -722,31 +722,28 @@ curl http://localhost/api/v1/users/image/8d6cca1c6bdc226cf2ba131e264ca2c7 -v -u
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def image
|
def image
|
||||||
|
|
||||||
# cache image
|
# cache image
|
||||||
response.headers['Expires'] = 1.year.from_now.httpdate
|
response.headers['Expires'] = 1.year.from_now.httpdate
|
||||||
response.headers['Cache-Control'] = 'cache, store, max-age=31536000, must-revalidate'
|
response.headers['Cache-Control'] = 'cache, store, max-age=31536000, must-revalidate'
|
||||||
response.headers['Pragma'] = 'cache'
|
response.headers['Pragma'] = 'cache'
|
||||||
|
|
||||||
file = Avatar.get_by_hash(params[:hash])
|
file = Avatar.get_by_hash(params[:hash])
|
||||||
|
|
||||||
if file
|
if file
|
||||||
|
file_content_type = file.preferences['Content-Type'] || file.preferences['Mime-Type']
|
||||||
|
|
||||||
|
return serve_default_image if ActiveStorage.content_types_allowed_inline.exclude?(file_content_type)
|
||||||
|
|
||||||
send_data(
|
send_data(
|
||||||
file.content,
|
file.content,
|
||||||
filename: file.filename,
|
filename: file.filename,
|
||||||
type: file.preferences['Content-Type'] || file.preferences['Mime-Type'],
|
type: file_content_type,
|
||||||
disposition: 'inline'
|
disposition: 'inline'
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
# serve default image
|
serve_default_image
|
||||||
image = 'R0lGODdhMAAwAOMAAMzMzJaWlr6+vqqqqqOjo8XFxbe3t7GxsZycnAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAMAAwAAAEcxDISau9OOvNu/9gKI5kaZ5oqq5s675wLM90bd94ru98TwuAA+KQAQqJK8EAgBAgMEqmkzUgBIeSwWGZtR5XhSqAULACCoGCJGwlm1MGQrq9RqgB8fm4ZTUgDBIEcRR9fz6HiImKi4yNjo+QkZKTlJWWkBEAOw=='
|
|
||||||
send_data(
|
|
||||||
Base64.decode64(image),
|
|
||||||
filename: 'image.gif',
|
|
||||||
type: 'image/gif',
|
|
||||||
disposition: 'inline'
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
@ -778,6 +775,11 @@ curl http://localhost/api/v1/users/avatar -v -u #{login}:#{password} -H "Content
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if ActiveStorage::Variant::WEB_IMAGE_CONTENT_TYPES.exclude?(file_full[:mime_type])
|
||||||
|
render json: { error: 'Mime type is invalid' }, status: :unprocessable_entity
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
begin
|
begin
|
||||||
file_resize = StaticAssets.data_url_attributes(params[:avatar_resize])
|
file_resize = StaticAssets.data_url_attributes(params[:avatar_resize])
|
||||||
rescue
|
rescue
|
||||||
|
@ -1061,4 +1063,15 @@ curl http://localhost/api/v1/users/avatar -v -u #{login}:#{password} -H "Content
|
||||||
|
|
||||||
render json: { message: 'ok' }, status: :created
|
render json: { message: 'ok' }, status: :created
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def serve_default_image
|
||||||
|
image = 'R0lGODdhMAAwAOMAAMzMzJaWlr6+vqqqqqOjo8XFxbe3t7GxsZycnAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAMAAwAAAEcxDISau9OOvNu/9gKI5kaZ5oqq5s675wLM90bd94ru98TwuAA+KQAQqJK8EAgBAgMEqmkzUgBIeSwWGZtR5XhSqAULACCoGCJGwlm1MGQrq9RqgB8fm4ZTUgDBIEcRR9fz6HiImKi4yNjo+QkZKTlJWWkBEAOw=='
|
||||||
|
|
||||||
|
send_data(
|
||||||
|
Base64.decode64(image),
|
||||||
|
filename: 'image.gif',
|
||||||
|
type: 'image/gif',
|
||||||
|
disposition: 'inline'
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -72,7 +72,6 @@ add avatar by url
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def self.add(data)
|
def self.add(data)
|
||||||
|
|
||||||
# lookups
|
# lookups
|
||||||
if data[:object]
|
if data[:object]
|
||||||
object_id = ObjectLookup.by_name(data[:object])
|
object_id = ObjectLookup.by_name(data[:object])
|
||||||
|
|
|
@ -1517,6 +1517,60 @@ RSpec.describe 'User', type: :request do
|
||||||
expect { make_request(avatar_full: base64, avatar_resize: base64) }
|
expect { make_request(avatar_full: base64, avatar_resize: base64) }
|
||||||
.to change { Avatar.list('User', user.id) }
|
.to change { Avatar.list('User', user.id) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'with a not allowed mime-type' do
|
||||||
|
let(:base64) { 'data:image/svg+xml;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==' }
|
||||||
|
|
||||||
|
it 'returns verbose error for a not allowed mime-type' do
|
||||||
|
make_request(avatar_full: base64)
|
||||||
|
expect(json_response).to include('error' => 'Mime type is invalid')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'GET /api/v1/users/image/:hash', authenticated_as: :user do
|
||||||
|
let(:user) { create(:user) }
|
||||||
|
let(:avatar_mime_type) { 'image/png' }
|
||||||
|
let(:avatar) do
|
||||||
|
file = File.open('test/data/image/1000x1000.png', 'rb')
|
||||||
|
contents = file.read
|
||||||
|
Avatar.add(
|
||||||
|
object: 'User',
|
||||||
|
o_id: user.id,
|
||||||
|
default: true,
|
||||||
|
resize: {
|
||||||
|
content: contents,
|
||||||
|
mime_type: avatar_mime_type,
|
||||||
|
},
|
||||||
|
source: 'web',
|
||||||
|
deletable: true,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
let(:avatar_content) { Avatar.get_by_hash(avatar.store_hash).content }
|
||||||
|
|
||||||
|
before do
|
||||||
|
user.update!(image: avatar.store_hash)
|
||||||
|
end
|
||||||
|
|
||||||
|
def make_request(image_hash, params: {})
|
||||||
|
get "/api/v1/users/image/#{image_hash}", params: params, as: :json
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns verbose error when full image is missing' do
|
||||||
|
make_request(avatar.store_hash)
|
||||||
|
expect(response.body).to eq(avatar_content)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with a not allowed inline mime-type' do
|
||||||
|
let(:avatar_mime_type) { 'image/svg+xml' }
|
||||||
|
|
||||||
|
it 'returns the default image' do
|
||||||
|
make_request(avatar.store_hash)
|
||||||
|
expect(response.headers['Content-Type']).to include('image/gif')
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET /api/v1/users/search, checks usage of the ids parameter', authenticated_as: :agent do
|
describe 'GET /api/v1/users/search, checks usage of the ids parameter', authenticated_as: :agent do
|
||||||
|
|
Loading…
Reference in a new issue