-
Notifications
You must be signed in to change notification settings - Fork 162
Toggle group ownership on projects #4792
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
base: master
Are you sure you want to change the base?
Conversation
apps/dashboard/app/models/project.rb
Outdated
| else | ||
| true | ||
| end | ||
| end |
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.
Even though this could be condensed by combining the 'None' case and the unset case, I left them separate so that we can replace true in the ternary with the ownership removal later. Otherwise we could simplify it to just
new_group = attributes.fetch(:group_owner, 'None')
(new_group == 'None') ? true : set_group_owner(new_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.
I don't see where this is being called from. Also - None value is likely dangerous if it's ever used. It should default to the users Primary group as that will always be a valid fallback.
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 already removed the 'None' option from the select, as that was only necessary when we were detecting the 'possible groups', which could have been an empty set. Now that we are detecting the user's groups directly, there is no way to submit 'None'. However I see how this could create issues, maybe just sticking with nil as the default is a better idea. It should still cause set_group_owner to rescue, but ideally without any unintended effects
apps/dashboard/app/models/project.rb
Outdated
| @directory = File.expand_path(@directory) unless @directory.blank? | ||
| @template = attributes[:template] | ||
|
|
||
| @group_owner = get_group_owner |
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.
Although this instance variable is not explicitly used, it is responsible for setting the initial value in the form
|
I don't think I'm a fan of modifying the directory after it's been created. I'd think this is needed in the project creation - but editing or changing it after the fact, I'm not so sure. I don't think changing the group/account/charge-back code after the fact is something that'll ever need to happen. This is because funds ($) are tied to this group/account/charge-back code. A new/different group/account/charge-back code is an entirely new project. Specifying it during project creation? Sure, I think that's needed. |
|
If we specify it during creation, we don't get to do the automagic detection of which groups it is 'shareable' with, since that depends on the location of the project root (unknown before initial creation). Of course this is all an alternative to specifying in the group level directory the proper default group ownership, but that moves the responsibility from the project owner to the center admin.
Isn't that the only way we can toggle projects from private to shared and vice versa? If charge schemes prevent us from modifying group ownership then we could not allow for mistakes to be made during project creation (which seems user-error prone) |
|
I am also trying to account for a universal shared directory where you want to limit your project to a specific group (but multiple groups have access to the parent). Is that something we should be accounting for or not? The use case I had in mind for this was the following interaction when working with non-primary groups This seems like a common enough occurrence that we should find a good solution to it, or putting this responsibility on the admin who creates the |
I don't think there is such a thing as a "universal shared directory" outside of maybe
If we're accounting for a mistake - then maybe - but Changing the ownership after the fact I think just sets us up for a lot of edge case failures. You'd want to
Not sure where you're getting the admin from here. If a user creates |
|
Ok the group selection option has now been enabled for the new page only, and the group is only shown on projects outside the user's home directory (potentially shared projects). We can return to group owner modification later, when we have a way to account for edge cases or have a clearer idea of what that should look like. |
| end | ||
|
|
||
| def user_groups | ||
| CurrentUser.groups.map(&:name) |
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.
CurrentUser already has this api.
ondemand/apps/dashboard/lib/current_user.rb
Lines 39 to 41 in c4d8536
| def group_names | |
| @group_names ||= groups.map(&:name) | |
| end |
apps/dashboard/app/models/project.rb
Outdated
| if new_record? | ||
| set_group_owner(@group_owner) | ||
| return | ||
| end |
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 should likely go into the save method. I don't think we should chmod during object creation as it may never actually get saved.
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.
Yeah that seems like a good idea
|
|
||
| def make_dir | ||
| project_dataroot.mkpath unless project_dataroot.exist? | ||
| set_group_owner |
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.
Can we actually move this to update_permissons - I feel like it fits better there.
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.
Errr.... actually it is fine here. We should maybe just pass 750 to mkpath here.
I say that it's fine here, because we'll also need to setgid bit for shared projects and we should do that before we make the other directories so that they're initialized under the correct 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.
It certainly would logically, but as soon as project_dataroot has files, we end up in the chmod -r scenario that could present a lot of complex cases. By intercepting it as soon as the project directory is created (before it has any contents) we make sure that the group ownership (and eventually setbit) setting can inform the creation of those project files
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.
We should maybe just pass 750 to mkpath here
I wonder if this prompts a reorganization to the setup steps here. Maybe we have a method make_root that just creates the root directory, and then fire them in the following order: make_root && update_permissions && make_dir.... That way all the permissions changes have the chance to apply before metadata files are created
| jobs_project_directory_error: Project directory path is not set for this workflow | ||
| jobs_project_directory_placeholder: Project directory absolute path | ||
| jobs_project_generic_error: 'There was an error processing your request: %{error}' | ||
| jobs_project_group_owner: Group owner |
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'm struggling a bit with the word owner here. While within the code base I can let it slip, but a user facing string is a bit different as it seems to collide with User (Owner) permission.
A quick google search indicates it's just group as in user (owner) - group - others (world or anonymous).
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.
So maybe a label like 'Create as group:' would be more accurate? Or maybe 'Create with group:' would be better. Or are you saying just 'group' by itself is clear enough?
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 may be overthinking it. Maybe it's fine.
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.
No I think it is an important thing to get right. We basically have to find a compromise between people with and without a working knowledge of linux, and be attentive to what will give the best understanding to everyone. 'Group owner' is almost bad both ways, as it is both confusing to someone who knows that groups cannot be an 'owner' of a file, and someone without that knowledge could mistakenly think they are doing just that, and voiding their personal ownership and control of the project. Especially without any auto-detection helping with the choice, it is important that people know that this is a necessary step for sharing their project.
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.
Maybe a little ? icon with hover-over text can help here.
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.
Yeah I like that. I think I'll probably go with 'Group' to be as minimal and accurate as possible, and then explain in the help text like Make sure to choose the group that includes all intended collaborators. If this is not a collaborative project, the default group is recommended
| end | ||
|
|
||
| def set_group_owner | ||
| return true if private? || @group_owner == get_group_owner |
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.
Since it's an att_reader we should prefer to use it instead of referencing the instance variable directly. I.e., group_owner instead of @group_owner.
Fixes #4780 by adding a form item to edit forms allowing you to set the group owner. This has a few parts to it:
Eventually I would like to show the group owner in the show page, but this is a proof of concept that gets the hard part out of the way. I also think we may want to move the permissions settings to their own modal on the show page (which would more elegantly handle the fact that these can only be set after project creation), but since there is a good deal of frontend work and usage planning that would have to go into that, placing it in the form is a quicker way to get the same functionality.
The one piece this is currently missing is the ability to remove group ownership once it is given. The only way I can think to do this currently is to find a group inside the intersection mentioned above so that only the owner can access, but I don't know if that is guaranteed to exist. That being said, we are eventually going to add options to change facl permissions, so maybe "setting the group owner to 'none'" is actually best implemented by removing group access altogether, though interpreting that correctly (like in
get_group_ownercould get complicated.The last special case here is that you can't use this to target intersections of groups. So if I (member of
group1andgroup2) create a project in a directory only accessible togroup2, I can't change the project owner togroup1knowing that a certain member ofgroup2is also a member ofgroup1(effectively sharing it just with them). In a specialized permissions pane, it would be nice to have a toggle that would ignore the "who can access the parent" filter, but I don't know if this is possible inside a form without getting too complicated.