-
Notifications
You must be signed in to change notification settings - Fork 470
Implement authorization to deploy apps #3044
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
Conversation
Implement UI for deployment group access control that shows all deployment groups but disables unauthorized ones. Features include: - Tooltip explaining authorization restrictions - Block cursor and disabled click handling - Mock authorization logic (production/staging disabled) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
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.
LGTM! Just some nits!
lib/livebook/teams.ex
Outdated
Deploys the given app deployment to given deployment group using a deploy key. | ||
""" | ||
@spec authorized_user_to_deploy?(Team.t(), Teams.DeploymentGroup.t()) :: boolean() | ||
def authorized_user_to_deploy?(%Team{} = team, %Teams.DeploymentGroup{} = deployment_group) do |
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.
def authorized_user_to_deploy?(%Team{} = team, %Teams.DeploymentGroup{} = deployment_group) do | |
def user_can_deploy?(%Team{} = team, %Teams.DeploymentGroup{} = deployment_group) do |
lib/livebook/teams/broadcasts.ex
Outdated
@@ -34,6 +34,7 @@ defmodule Livebook.Teams.Broadcasts do | |||
* `{:deployment_group_created, DeploymentGroup.t()}` | |||
* `{:deployment_group_updated, DeploymentGroup.t()}` | |||
* `{:deployment_group_deleted, DeploymentGroup.t()}` | |||
* `{:deployment_authorization_updated, DeploymentGroup.t()}` |
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 authorisation here can be ambiguous. Perhaps one can think it is about the authorized users? What about:
* `{:deployment_authorization_updated, DeploymentGroup.t()}` | |
* `{:deployment_users_updated, DeploymentGroup.t()}` |
if(@active, | ||
do: "border-blue-600 bg-blue-50", | ||
else: "border-gray-200" | ||
) | ||
), | ||
!@authorized && "opacity-50 bg-gray-50" |
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.
Keep in mind the order specified in "class" does not matter. Therefore, there is no guarantee bg-gray-50 will override the ones above. You need to replace the above into a cond instead:
cond do
!@authorized -> "tooltip top select_deployment_group"
@active -> "border-blue-600 bg-blue-50"
true -> "border-gray-200"
end
@selectable && @authorized && "cursor-pointer", | ||
@selectable && !@authorized && "cursor-not-allowed", |
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.
@selectable && @authorized && "cursor-pointer", | |
@selectable && !@authorized && "cursor-not-allowed", | |
@selectable && if(@authorized, do: "cursor-pointer", else: "cursor-not-allowed"), |
]} | ||
phx-click={@selectable && "select_deployment_group"} | ||
style={!@authorized && "display: block !important;"} |
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.
Is there a way to not use style=
? 🤔
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.
Oops, I forgot to change to class
lib/livebook/hubs/team_client.ex
Outdated
def authorized_user_to_deploy?(id, user_id, deployment_group_id) do | ||
GenServer.call( | ||
registry_name(id), | ||
{:check_deployment_authorization, user_id, deployment_group_id} |
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.
Btw, if you want another name, you could call it this:
def authorized_user_to_deploy?(id, user_id, deployment_group_id) do | |
GenServer.call( | |
registry_name(id), | |
{:check_deployment_authorization, user_id, deployment_group_id} | |
def user_can_deploy?(id, user_id, deployment_group_id) do | |
GenServer.call( | |
registry_name(id), | |
{:user_can_deploy?, user_id, deployment_group_id} |
It is shorter and reads a bit nicer. :)
lib/livebook/hubs/team_client.ex
Outdated
state.deployment_group_id == deployment_group.id and | ||
(current_deployment_group.authorization_groups != | ||
deployment_group.authorization_groups or | ||
current_deployment_group.groups_auth != deployment_group.groups_auth or | ||
current_deployment_group.teams_auth != deployment_group.teams_auth) -> | ||
Teams.Broadcasts.server_authorization_updated(deployment_group) | ||
|
||
state.deployment_group_id == nil and | ||
(current_deployment_group.deployment_users != | ||
deployment_group.deployment_users or | ||
current_deployment_group.deploy_auth != deployment_group.deploy_auth) -> | ||
Teams.Broadcasts.deployment_authorization_updated(deployment_group) |
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.
Technically both clauses could be the case? The current UI may imply that only one of these is true at a time, but we could not make this assumption and have two separate ifs
instead?
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.
LGTM!
No description provided.