-
Notifications
You must be signed in to change notification settings - Fork 118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update MediaSourceService.php #930
base: 2.x
Are you sure you want to change the base?
Conversation
// Check if the directory is writable. | ||
if (!is_writable(dirname($directory))) { | ||
$parent_directory = dirname($directory); | ||
$error_current_user = shell_exec('whoami'); | ||
$sanitized_current_user = str_replace(array("\n", "\r"), '', $error_current_user); | ||
throw new HttpException(500, "The user '$sanitized_current_user' does not have permissions to write to: '$parent_directory' . Error"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is kind of contrary to the next lines, where a given (sub)directory might not yet exist, and the ->prepareDirectory()
call is intended to create it, with the FileSystemInterface::CREATE_DIRECTORY
bit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additionally, if there's any chance of these messages being emitted to browsers, I'm not sure that it's particularly appropriate to include things like the names of OS-level users and the directory? Like... sure, if we want to write them to logs for the consumption of users privileged to read them, that's one thing, but displaying to general users, not so much?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think @adam-vessey is right; although I wouldn't object to the whoami bit being moved into the following if statement so that 500 error could read something like "The destination directory does not exist, could not be created, or is not writable by $current_user: $directory".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. Instead of adding this onto the thrown 500 exception, we could use \Drupal::logger('islandora')->warning()
or whatever the dependency injection equivalent is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@adam-vessey I can move stuff into the existing one. I don't believe these are (I haven't seen them show up in the browser). I wasn't sure how much info is too much but right now it's not enough (in my opinion). Giving the user the directory is actionable. Telling them the username is probably fine but most people use usernames like nginx or www-data which is kinda standard so I wasn't sure how significant that would be for having in the logs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After thinking about it I do think the added value shouldn't be in a new if statement but included (if at all) in the existing one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oddly enough, that error only really fires when derivatives generation is needing to create a new folder. It may just be how I'm testing this. But I thought it would be worth noting.
$error_current_user = shell_exec('whoami'); | ||
$sanitized_current_user = str_replace(["\n", "\r"], '', $error_current_user); | ||
$error_message = "The destination directory does not exist, could not be created, or is not writable by $sanitized_current_user: $directory"; | ||
$this->logger->error($error_message); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is throwing a null error:
[Tue Apr 11 17:28:11.009894 2023] [php:warn] [pid 36294] [client 127.0.0.1:42242] PHP Warning: Undefined property: Drupal\\islandora\\MediaSource\\MediaSourceService::$logger in /var/www/html/drupal/web/modules/contrib/islandora/src/MediaSource/MediaSourceService.php on line 298
[Tue Apr 11 17:28:11.014440 2023] [php:notice] [pid 36294] [client 127.0.0.1:42242] Error: Call to a member function error() on null in /var/www/html/drupal/web/modules/contrib/islandora/src/MediaSource/MediaSourceService.php on line 298 #0 /var/www/html/drupal/web/modules/contrib/islandora/src/Controller/MediaSourceController.php(168): Drupal\\islandora\\MediaSource\\MediaSourceService->putToNode(Object(Drupal\\node\\Entity\\Node), Object(Drupal\\media\\Entity\\MediaType), Object(Drupal\\taxonomy\\Entity\\Term), Resource id #24, 'image/jpeg', 'public://2023-0...')\n#1 [internal function]: Drupal\\islandora\\Controller\\MediaSourceController->putToNode(Object(Drupal\\node\\Entity\\Node), Object(Drupal\\media\\Entity\\MediaType), Object(Drupal\\taxonomy\\Entity\\Term), Object(Symfony\\Component\\HttpFoundation\\Request))\n#2 /var/www/html/drupal/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array)\n#3 /var/www/html/drupal/web/core/lib/Drupal/Core/Render/Renderer.php(580): Drupal\\Core\\EventSubscriber\\EarlyRenderingControllerWrapperSubscriber->Drupal\\Core\\EventSubscriber\\{closure}()\n#4 /var/www/html/drupal/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\\Core\\Render\\Renderer->executeInRenderContext(Object(Drupal\\Core\\Render\\RenderContext), Object(Closure))\n#5 /var/www/html/drupal/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\\Core\\EventSubscriber\\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)\n#6 /var/www/html/drupal/vendor/symfony/http-kernel/HttpKernel.php(169): Drupal\\Core\\EventSubscriber\\EarlyRenderingControllerWrapperSubscriber->Drupal\\Core\\EventSubscriber\\{closure}()\n#7 /var/www/html/drupal/vendor/symfony/http-kernel/HttpKernel.php(81): Symfony\\Component\\HttpKernel\\HttpKernel->handleRaw(Object(Symfony\\Component\\HttpFoundation\\Request), 1)\n#8 /var/www/html/drupal/web/core/lib/Drupal/Core/StackMiddleware/Session.php(58): Symfony\\Component\\HttpKernel\\HttpKernel->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)\n#9 /var/www/html/drupal/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\\Core\\StackMiddleware\\Session->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)\n#10 /var/www/html/drupal/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\\Core\\StackMiddleware\\KernelPreHandle->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)\n#11 /var/www/html/drupal/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\\page_cache\\StackMiddleware\\PageCache->pass(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)\n#12 /var/www/html/drupal/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\\page_cache\\StackMiddleware\\PageCache->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)\n#13 /var/www/html/drupal/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\\Core\\StackMiddleware\\ReverseProxyMiddleware->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)\n#14 /var/www/html/drupal/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\\Core\\StackMiddleware\\NegotiationMiddleware->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)\n#15 /var/www/html/drupal/web/core/lib/Drupal/Core/DrupalKernel.php(713): Stack\\StackedHttpKernel->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)\n#16 /var/www/html/drupal/web/index.php(19): Drupal\\Core\\DrupalKernel->handle(Object(Symfony\\Component\\HttpFoundation\\Request))\n#17 {main}
Also, despite this not working, the file module is already giving me an error about file permissions for the folder in question: "The file permissions could not be set on public://2023-04."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to setup a private variable of $logger
and then add an argument of type LoggerInterface
to the __construct
or and then add @logger.channel.islandora
to the array of arguments in the islandora.services.yml
Also, $parent_directory
is never referenced and I'm not sure why we need to go through the work to get the username. It should be the user running your webserver, which you should know or be able to check with a ps -ef | grep (nginx|httpd|apache2)
It seems like this issue relates to handling filesystem restrictions with more clarity. (It would be helpful to give this PR a meaningful subject line, rather than naming the modified file; that could better communicate intent.) There's no existing usage of The user that PHP runs as is unlikely to be "dynamic" - the important information to capture IMO is that the webserver/application was unable to create a directory in that location. (I see this is noted in #930 (comment) also.) |
I'm not sure if this is ideal or if it's just overwriting the existing check
islandora/src/MediaSource/MediaSourceService.php
Line 302 in 5585f89
GitHub Issue: N/A
What does this Pull Request do?
When the media script tries to write to a directory (like
public://
) and the path is not set or has the wrong permissions, the error message could provide more informative information and be less cryptic.What's new?
How should this be tested?
Trigger media script to generate derivative
Go to /admin/content and click the drop-down and select "Image - Generate a thumbnail from an original file" and in the list of content items check the box next to an object that has a model = Image
It really doesn't matter which derivative you generate. This just needs to create a file. You just create a new media or something. All that matters is that the media script is trying to write to the error logs when a file save/update fails due to permissions issues.
To check that it worked
In this example, the directory resolves to
public://
instead of a real absolute path.To reset back and test with the proper permissions to verify this doesn't trigger when it shouldn't
An explanation for the above chmod command.
Now run the instructions above on "Trigger media script to generate derivative" and then check the error logs. There should be no error message.
Documentation Status
Additional Notes:
N/A
Interested parties
@Islandora/committers