Make sure write-protected files can only be forked (#182)

* Format file errors into readable messages

* Make sure write-protected files can only be forked

* Show tooltip when the file is write protected
This commit is contained in:
Jonatan Kłosko 2021-04-14 16:27:35 +02:00 committed by GitHub
parent f31428739f
commit 9e026ee4b9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 6 deletions

View file

@ -675,7 +675,8 @@ defmodule Livebook.Session do
handle_operation(state, {:mark_as_not_dirty, self()})
else
{:error, reason} ->
broadcast_error(state.session_id, "failed to save notebook - #{reason}")
message = :file.format_error(reason)
broadcast_error(state.session_id, "failed to save notebook - #{message}")
state
end
else

View file

@ -57,10 +57,15 @@ defmodule LivebookWeb.HomeLive do
<%= live_patch "Join session", to: Routes.session_path(@socket, :page, session_id_by_path(@path, @session_summaries)),
class: "button button-blue" %>
<% else %>
<%= content_tag :button, "Open",
class: "button button-blue",
phx_click: "open",
disabled: not path_openable?(@path, @session_summaries) %>
<%= tag :span, if(File.regular?(@path) and not file_writable?(@path),
do: [class: "tooltip top", aria_label: "This file is write-protected, please fork instead"],
else: []
) %>
<%= content_tag :button, "Open",
class: "button button-blue",
phx_click: "open",
disabled: not path_openable?(@path, @session_summaries) %>
</span>
<% end %>
</div>
<% end %>
@ -170,7 +175,7 @@ defmodule LivebookWeb.HomeLive do
end
defp path_openable?(path, session_summaries) do
File.regular?(path) and not path_running?(path, session_summaries)
File.regular?(path) and not path_running?(path, session_summaries) and file_writable?(path)
end
defp path_running?(path, session_summaries) do
@ -178,6 +183,13 @@ defmodule LivebookWeb.HomeLive do
path in running_paths
end
defp file_writable?(path) do
case File.stat(path) do
{:ok, stat} -> stat.access in [:read_write, :write]
{:error, _} -> false
end
end
defp create_session(socket, opts \\ []) do
case SessionSupervisor.create_session(opts) do
{:ok, id} ->