Skip to content

chore: implement deleting custom roles #14101

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

Merged
merged 9 commits into from
Aug 7, 2024
Merged

chore: implement deleting custom roles #14101

merged 9 commits into from
Aug 7, 2024

Conversation

Emyrk
Copy link
Member

@Emyrk Emyrk commented Aug 1, 2024

When deleting a custom role, the role can still be assigned to a user.

Copy link
Member Author

Emyrk commented Aug 1, 2024

This stack of pull requests is managed by Graphite. Learn more about stacking.

Join @Emyrk and the rest of your teammates on Graphite Graphite

@Emyrk Emyrk force-pushed the stevenmasley/delete_role branch from 31f7fe5 to cb91471 Compare August 1, 2024 20:07
@Emyrk Emyrk force-pushed the stevenmasley/org_role_routes branch from 43cbd73 to 938634d Compare August 2, 2024 19:42
@Emyrk Emyrk force-pushed the stevenmasley/delete_role branch from cb91471 to 9225eb1 Compare August 2, 2024 20:16
Base automatically changed from stevenmasley/org_role_routes to main August 5, 2024 18:42
@Emyrk Emyrk force-pushed the stevenmasley/delete_role branch from 9225eb1 to 2aa9875 Compare August 6, 2024 16:57
@Emyrk Emyrk marked this pull request as ready for review August 6, 2024 19:22
@Emyrk Emyrk force-pushed the stevenmasley/delete_role branch from 9d2a42f to f4739c9 Compare August 6, 2024 19:41
@Emyrk Emyrk requested a review from f0ssel August 6, 2024 19:54
Copy link
Member

@aslilac aslilac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm!

Comment on lines 166 to 170
OrganizationID: organization.ID,
},
},
ExcludeOrgRoles: false,
OrganizationID: organization.ID,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weird duplication of OrganizationID 🤔

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, it actually is not necessary, but we have a linter that makes you fill out all fields in a struct. This felt more intuitive that doing uuid.Nil. But you have to do something, or the linter yells at you 😢

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tldr on why this field can't be removed?

httpapi.InternalServerError(rw, err)
return
}
aReq.New = database.CustomRole{}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clever 😄

Comment on lines 1 to 35
-- When a custom role is deleted, we need to remove the assigned role
-- from all organization members that have it.
-- This action cannot be reverted, so deleting a custom role should be
-- done with caution.
CREATE OR REPLACE FUNCTION remove_organization_member_role()
RETURNS TRIGGER AS
$$
BEGIN
-- Delete the role from all organization members that have it.
-- TODO: When site wide custom roles are supported, if the
-- organization_id is null, we should remove the role from the 'users'
-- table instead.
IF OLD.organization_id IS NOT NULL THEN
UPDATE organization_members
-- this is a noop if the role is not assigned to the member
SET roles = array_remove(roles, OLD.name)
WHERE
-- Scope to the correct organization
organization_members.organization_id = OLD.organization_id;
END IF;
RETURN OLD;
END;
$$ LANGUAGE plpgsql;


-- Attach the function to deleting the custom role
CREATE TRIGGER remove_organization_member_custom_role
BEFORE DELETE ON custom_roles FOR EACH ROW
EXECUTE PROCEDURE remove_organization_member_role();


COMMENT ON TRIGGER
remove_organization_member_custom_role
ON custom_roles IS
'When a custom_role is deleted, this trigger removes the role from all organization members.';
Copy link
Contributor

@f0ssel f0ssel Aug 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I generally prefer this logic to live in app code in some sort of helper function, probably in a tx. I don't think this has to be changed here since I'm not sure how the team at large feels about this kind of design, but wanted to point out that I think it's easier to follow execution flow and also easier to update the behavior as well since changing this behavior now requires knowledge of sql triggers.

I see the benefits from a data integrity standpoint. Does this serve as some sort of performance advantage as well?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, I generally agree with you. In this case the data integrity is a security critical thing though.

Currently when making a new custom_role, you have to have a superset of the permissions to make it. So you cannot make a role that has greater privilege than yourself.

You could imagine a scenario where a role is created with a small set of perms, then deleted. Then a new role is created with the same name that has more permissions, and because a user had the old role, they are granted this new one.

At present, this would be less malicious, and more likely a mistake based on our roles, but the problem still remains.


So essentially, I choose the trigger as a security guarantee. We have some prior art for this for deleting user api keys.

A golang helper function just feels less safe imo.

Comment on lines 166 to 170
OrganizationID: organization.ID,
},
},
ExcludeOrgRoles: false,
OrganizationID: organization.ID,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tldr on why this field can't be removed?

@Emyrk Emyrk force-pushed the stevenmasley/delete_role branch from e72061a to e8f57fe Compare August 7, 2024 17:21
@Emyrk
Copy link
Member Author

Emyrk commented Aug 7, 2024

tldr on why this field can't be removed?

We have a linter that requires all struct fields be explicitly set. So you could put uuid.Nil and it would still work, just felt like it might confuse someone else to see a uuid.Nil 🤷‍♂️

@Emyrk Emyrk merged commit 2c13797 into main Aug 7, 2024
28 checks passed
@Emyrk Emyrk deleted the stevenmasley/delete_role branch August 7, 2024 17:37
@github-actions github-actions bot locked and limited conversation to collaborators Aug 7, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants