-
Notifications
You must be signed in to change notification settings - Fork 14
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
Go through GroupManager for group deletion #92
Conversation
253e510
to
06295d5
Compare
* | ||
* @param string $gid group id | ||
*/ | ||
public function deleteGroup($gid) { |
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 have the interface at hand, but this method should handle error cases somehow. What if the group can't be deleted? It should either throw a specific exception or return true / false to indicate success or failure.
I don't like the approach. The main problem I see is that there is a cyclic dependency with the core's group manager, which is quite scary and we should avoid. I think this should be handled by core somehow. Maybe the deletion should be done by core and the backend would just need to notify about it somehow. This might need architectural changes 😫 |
Not exactly. My feeling is that we should move to only use core's group manager in the end, see #91 So the customgroups UI + DAV layer would only use the Group Manager, and the Group Manager talks to the Group Backend provided by the app. But the Group Backend in customgroups does not depend on the Group Manager. |
@jvillafanez the other solution I dislike even more is to manually trigger the OC\Group::deleteGroup events from inside the DAV code onto the GroupManager instance. |
Although I'll have to check what we have now, I'd rather try an observer pattern here. Basically, the backend would have a couple of methods to register observers. These observers would be notified by the backend via The key point is that the core's group manager will be registered as observer when the backend is registered in the core's group manager. This way we achieve several things:
|
I understand your point. This reminds me that we already have Symfony dispatcher events which do not require a target object. So we could actually just listen to those in the Application class and rewire them to the IGroupManager instance. This would need tweaking of their parameters as some info is missing. Would you agree with the latter approach ? |
I think the symfony's dispatcher is too wide for this. The backend will have an empty list of observers, and it will add the observers there. When an event needs to be notified, it will be notified to all of the observers in the list. Just traversing the list is enough. There is no need for the backend to check anything about the elements in the list. |
Ok, indeed it is too wide. The symfony dispatcher was originally added by @sharidas to be able to catch the events in the audit app. If we trigger regular \OC\Group events then the audit app will get these anyway. One thing about symfony dispatcher though: the reason we want to use it more often is to avoid the observer pattern on individual objects. Observer pattern is fine for big objects like IGroupManager but for individual objects like IGroup it is not suitable because one would need to first get a list of all possible groups to be able to register events on each one of them. |
I think there are a couple of things to consider in order to choose using either an observer or the symfony's dispatcher (aka, mediator): the intrinsic dependency among the components, which for this particular case is something like a parent-child relationship (being the core's group manager as the parent and each backend as the child), and also the lifespan of the affected components. For our particular case, there is an obvious dependency between the core's group manager and the backends. Ideally, the backends shouldn't live outside the core's group manager, and every access should be done through core. This also means that the lifespan of the backend objects should be dependent of the lifespan of the core's group manager, so if the core's group manager stop existing somehow, then the backends should do the same. Using the symfony's dispatcher as mediator is fine if we don't expect explicit dependencies between the components and the lifespan among them is independent. This is the case of the communication among several apps. Some of the components might be disabled or not present, but the system should keep running without any problem; there shouldn't be any bugs caused by a component being disabled. On the other hand, if we must make sure groups are handled properly in any situation, I don't think there is any other option than going always through the core's group manager for any operation. This means that direct access to the backend is forbidden because we can't guarantee the core's group manager will be notified about the changes (core's group manager would be expected to self-register as an observer when the backends are registered in it, but it isn't expected that the app do this by itself). |
Yeah, I'm also wondering if we shouldn't just stick to always go through the core Group Manager. In this case the custom groups UI really is just a "better" UI than the usual group management stuff, except that it limits itself to custom groups. Originally I decided to bypass the group manager mostly because we hadn't invented the concept of scopes yet. So this was a way to prevent custom groups to be visible in the users page by having it not implement certain methods. Now that we have the scope concept, there might not be anything preventing us to go through the group manager directly. |
The whole user and group management should have an architectural review, and check what we can do to improve it short term and long term. Just this is a lot of work to do. Making "user management 2.0" would be really nice but I don't think we'll able to start implementing something until 2019. |
I suggest we move this to the next version to give us more time to settle on a solution |
@jvillafanez so what middle ground should we use ? |
Honestly, the user management is more chaotic than homer simpson's web page. Let's see if we can have some clear responsabilities:
Now, what I don't understand is where all the dav code is in the architecture. My guess is that it should be on top the core's group manager and act as a controller. If this is the case, the customgroups shouldn't need to know anything about it. I think we can sum up all of this in the question "why do we need direct access to the backend?" and then the follow up question: "if we need direct access, why the backend doesn't have the tools to notify changes?"
I don't have easy solutions other than limit the mess to the minimum, which in this case would be use the core's group manager only where it's needed. Other solutions will need heavy changes:
|
It already does that with the hook events when calling
The sharing code already has safeties in place in case it finds shares pointing to non-existing users or groups, in which case the share is discarded from the result list, but not deleted on the fly.
The DAV code of customgroups is only its API layer. The actual logic should be done by either the helper, service classes or the custom groups backend.
This is what this PR does: it only uses the core group manager for the delete operation, for now.
Same as above, for shares at least. But it only happens in cron.
It would already be possible by using this event: https://github.com/owncloud/core/blob/master/lib/private/Group/Manager.php#L88. Also see https://github.com/owncloud/core/blob/master/lib/private/Group/Group.php#L269. The main problem here is that the listener expects us to pass a So keep this PR as is to match "use the core's group manager only where it's needed" or introduce group backend events that the group manager listens to in core to match "Add support to notify changes from the backend to the core's manager. This will require changes in core and probably in any other app that handle users and groups." ? |
This is where the user management architecture fails quite bad. The customgroups app should be able to generate their own Anyway, taking into account that it will require architectural changes that won't happen in the short term, I guess will need to go with this PR and inject the core's user manager |
Indeed, this bit bothered me as well. |
Another little concern is that now if we trigger the core hooks, some apps (audit_log) will receive two events: the customgroups special one and also the core delete one. Not that bad though. |
This will trigger the delete events and make sure that related shares get automatically deleted
06295d5
to
368be2d
Compare
Rebased |
Code-wise this is fine 👍 If this is urgent we'll need to go with this code. I don't have better solutions without requiring heavy changes. |
Ok it works. Tested with core's stable10 and master. 👍 |
This will trigger the delete events and make sure that related shares
get automatically deleted.
Fixes #89
Also ref #91