inveniosoftware / invenio-app-rdm

Turn-key research data management platform.
https://inveniordm.docs.cern.ch
MIT License
101 stars 146 forks source link

communities: logo upload fails when using S3 storage #1867

Open tmorrell opened 2 years ago

tmorrell commented 2 years ago

Package version (if known): v9.1

Describe the bug

Uploading a community image doesn't work if your repository is set up to use S3 storage.

Steps to Reproduce

  1. Set up a repository using S3 storage
  2. Create a new community
  3. Upload a logo
  4. See error Screen Shot 2022-09-08 at 3 09 47 PM

Traceback (most recent call last): lib/python3.8/site-packages/flask/app.py", line 1523, in full_dispatch_request /lib/python3.8/site-packages/flask/app.py", line 1509, in dispatch_request#012 return self.ensure_sync(self.view_functions[rule.endpoint])(req.view_args) lib/python3.8/site-packages/flask_resources/resources.py", line 65, in view#012 return view_meth()#012
/lib/python3.8/site-packages/flask_resources/content_negotiation.py", line 116, in inner_content_negotiation#012 return f(*args, *kwargs)#012
lib/python3.8/site-packages/flask_resources/parsers/decorators.py", line 51, in inner#012 return f(self,
args,
kwargs) lib/python3.8/site-packages/invenio_communities/communities/resources/resource.py", line 169, in read_logo#012 item = self.service.read_logo(#012
lib/python3.8/site-packages/invenio_communities/communities/services/service.py", line 197, in read_logo raise FileNotFoundError()#012FileNotFoundErro

Expected behavior

Logo is uploaded and stored successfully

Screenshots (if applicable)

Additional context

github-actions[bot] commented 1 year ago

This issue was automatically marked as stale.

marijane commented 1 year ago

We are hosting our system on AWS and we are hitting this issue, what would need to happen to get it fixed?

tmorrell commented 1 year ago

This logo upload is improved on v12b1, but doesn't seem to be completely fixed yet. Most logos now work, but they seem inconsistent (sometimes they load, sometimes they don't).

I'm not sure what would be needed to backport these improvements to v9.

github-actions[bot] commented 1 year ago

This issue was automatically marked as stale.

zguillen commented 7 months ago

We also came across this issue and fixed it by customizing the route that gets the logo. We con't use the RDM UI for projects so it was easy to have our UI call our custom route to get it, however once you know the route RDM's UI is calling you can override it from your extension:

from invenio_files_rest.helpers import send_stream
...
@blueprint.route("/projects/<string:project_slug>/logo")
def get_logo(project_slug):
    with AwsSession() as aws_session:
        community_service: CommunityService = current_communities.service
        current_project = community_service.read(
            identity=system_identity, id_=project_slug.lower()
        )

        logo_file_item = community_service.read_logo(
            system_identity,
            current_project.id,
        )

        s3_endpoint_url = os.environ.get("INVENIO_S3_ENDPOINT_URL")
        if s3_endpoint_url:
            stream = logo_file_item.send_file()

            s3_full_url = stream.response[
                0
            ].decode()  # looks like https://s3.us-west-2.amazonaws.com/rdm-dev-s3-data/rdm-dev-s3-data/c9/13/cccd-366f-471c-82b0-0739f52c8d84/data?response-content-t ...
            bucket_path = s3_full_url.replace(s3_endpoint_url, "").split("?")[0]
            if bucket_path.startswith("/"):
                bucket_path = bucket_path[1:]
            s3_client = aws_session.s3_client
            first_slash = bucket_path.find("/")
            bucket_name = bucket_path[0:first_slash]

            logo_object = s3_client.get_object(Bucket=bucket_name, Key=bucket_path)
            stream = logo_object.get("Body")
            size = logo_object.get("ContentLength")
            mimetype = logo_object.get("ContentType")

            return send_stream(stream, "logo", size, None, mimetype=mimetype), 200

        return logo_file_item.send_file(), 200