Closed mairin closed 3 years ago
Sure, I've assigned it to you @EUGINELETHAL!
@EUGINELETHAL @mairin I think this is quite a complicated issue for an intern that's just getting familiar with the project.
Currently a plugin meta is created by a user and that user is the owner. The owner can then add another user as owner. Any owner can in turn add another user as owner. Owners of a plugin meta can also publish new versions of the plugin and update the public_repo
property of the plugin meta. This is a very limited way users can collaborate on the same plugin.
@mairin Could you please explain what exactly this issue is about? How do groups and teams work?
@jbernal0019 @mairin mentioned that it is something like how github organizations work, this is how i have designed my models class Group(models.Model): name = models.CharField(max_length=255) created_at = models.DateTimeField(auto_now_add=True) last_updated_on = models.DateTimeField(auto_now=True) is_active = models.BooleanField(default=True) owner = models.ForeignKey('auth.User', related_name='owned_plugin_metas', on_delete=models.CASCADE)
class Member(models.Model): MEMBER_TYPECHOICES = ( ('A', ('Admin')), ('M', _('Maintainer')) ) group = models.ForeignKey(group,related_name="group_members",on_delete=models.CASCADE) member= models.ForeignKey('auth.User',on_delete=models.CASCADE) created_at= models.DateTimeField(auto_now_add=True) last_updated_on':= models.DateTimeField(auto_now=True) role = models.CharField(max_length=1, choices=MEMBER_TYPE_CHOICES)
@jbernal0019 @mairin the team members have the same role of admin or other team members can have different roles
@jbernal0019 I think based on how owners can add additional new owners, where teams could be helpful is as a shorthand for adding a bunch of people to a plugin at once. So say if there is 10 people on a team, and they manage 5 plugins... instead of having to add 9 others people to each of 5 plugins... the 10 people could be made into a group (Say group @Team), and that group added as an owner.
Then, if someone leaves, you would remove them from @Team and they would be removed from all 5 plugins at once. Rather than having to track down every plugin they might possibly have perms on and remove them manually x5.
So what I think would be needed is a model to add the concept of teams, then the following kinds of methods -
And the methods that exist for adding/removing owners from plugins, would need to also be able to accept either a username or a team name.
Does this make sense?
@EUGINELETHAL I wanted to catch you up here on the discussion we had in Slack - I added you to the room too but I think it would be handy to have the notes here.
@jbernal0019 thought the above comment ^ was reasonable, and would like us to follow the team/group model of pypi.org (which sounds really similar to what we discussed as a subset of what GitHub allows.) Here is @jbernal0019 's description of that:
Basically they call collaborators to what we call here teams
There are two types of roles owner and maintainer
An owner can invite a new collaborator and assign it one of the roles owner or mantainer
An owner can remove another collaborator ( owner or maintainer)
An owner can delete the app, etc…
A maintainer seems to be able to just publish new versions of the app (plugins in ChRIS store)
Interestingly Pypi shows me a sort of a warning badge (yellow) when I am the sole owner of a package
There are two possible roles for collaborators:
Maintainer Can upload releases for a package. Cannot invite collaborators. Cannot delete files, releases, or the project.
Owner Can upload releases. Can invite other collaborators. Can delete files, releases, or the entire project.
Obviously the simplest team implementation would be one with a single role: owner
What I would recommend @EUGINELETHAL is to rename "admin" to "owner" and rename "team" to "collaborators" - then anyone familiar with PyPi using the ChRIS store will recognize the model right away and better pick it up.
Does this make sense / seem doable?
@EUGINELETHAL @mairin I'm going to work on this issue myself because it's quite complicated for someone not familiar with the underlying ChRIS Store DB schema. In fact after looking a bit closer at this issue I've figured out that the engineers that implemented PyPI had very good reasons for these two strange constraints:
The reasoning behind this has to do with not allowing a package to exist without having at least a single owner. Concurrency (e.g. two owners trying to downgrade themselves at the same time) also becomes a problem here if you remove the above constraints. In summary this is not a straightforward issue.
@jbernal0019 Makes sense. Is there any chunk of the work or something related that @EUGINELETHAL could take on here that could be better scoped for an Outreachy initial contribution?
@jbernal0019 if you allow me let me give it a shot today, and over the weekend cause I was researching on it and was just getting the concept,probably you will assist me in advanced concepts where I may be stuck like handling some of the permissions
Any chance you can remove me from this thread? I'm not the jbernal in question.
José Bernal Web/Application Engineer Cell 541-228-8481 @.***
On Wed, Apr 7, 2021 at 10:48 PM Eugine Ochung @.***> wrote:
class PluginMeta(models.Model): """ Model class that defines the meta info for a plugin that is the same across plugin's versions. If a user owns and/or is a fan of a plugin's meta then he/she owns and/or is a fan of all the plugin's versions. """ creation_date = models.DateTimeField(auto_now_add=True) modification_date = models.DateTimeField(auto_now_add=True) name = models.CharField(max_length=100, unique=True) title = models.CharField(max_length=400, blank=True) public_repo = models.URLField(max_length=300) license = models.CharField(max_length=50, blank=True) type = models.CharField(choices=PLUGIN_TYPE_CHOICES, default='ds', max_length=4) icon = models.URLField(max_length=300, blank=True) category = models.CharField(max_length=100, blank=True) authors = models.CharField(max_length=200, blank=True) documentation = models.CharField(max_length=800, blank=True) fan = models.ManyToManyField('auth.User', related_name='favorite_plugin_metas', through='PluginMetaStar') owner = models.ForeignKeyField('Team', related_name='owned_plugin_metas')
class Team(models.Model): name = models.CharField(max_length=255) creation_date = models.DateTimeField(auto_now_add=True) modification_date = models.DateTimeField(auto_now=True) is_active = models.BooleanField(default=True) owner = models.ForeignKey('auth.User','related_name="teams",on_delete=models.CASCADE) collaborators=models.ManyToManyField('auth.User')
class collaborator(models.Model): COLLABORATOR_ROLECHOICES = ( ('O', ('Owner')), ('M', _('Maintainer')) user= models.ForeignKey('auth.User',on_delete=models.CASCADE) created_at= models.DateTimeField(auto_now_add=True) last_updated_on':= models.DateTimeField(auto_now=True) role = models.CharField(max_length=1, choices=MEMBER_TYPE_CHOICES)
method for creating team"
teama=Team.objects.create(owner="Eugine", name="teama")
method for adding collaborator
new_maintainer = teama.collaborators.create(user=Duffy",role="maintainer") new_owner=teama.collborators.create(user=Jorge, role="owner")
method for removing collaborator
teama.collaborators.remove(new_maintainer") @jbernal0019 https://github.com/jbernal0019 @mairin https://github.com/mairin this is a basic snippet of how i thought the models and model methods should look like before considering advanced permissions
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/FNNDSC/ChRIS_store/issues/27#issuecomment-815466950, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAT2QPSFWQ6EOPE6ZWZU6ZDTHU7ULANCNFSM4QNEQQYA .
@jbernal0019 Makes sense. Is there any chunk of the work or something related that @EUGINELETHAL could take on here that could be better scoped for an Outreachy initial contribution?
@mairin I don't think so for now.
@mairin @EUGINELETHAL
PyPI's collaborators-based user model is now implemented for the ChRIS store backend. The ChRIS store frontend JS client also has new methods to add collaborators to a plugin (Client.createPluginCollaborator
), show a plugin's collaborators and their role (PluginMeta.getCollaborators
) and for each user the plugins it collaborates on (Client.getCollabPluginMetas
).
https://fnndsc.github.io/fnndsc/chrisstoredoc/class/src/client.js~Client.html#instance-method-createPluginCollaborator https://fnndsc.github.io/fnndsc/chrisstoredoc/class/src/client.js~Client.html#instance-method-getCollabPluginMetas https://fnndsc.github.io/fnndsc/chrisstoredoc/class/src/pluginmeta.js~PluginMeta.html#instance-method-getCollaborators
We need somebody to implement this model in the ChRIS store UI. Basically the same user interface as PyPI's.
@mairin interested on working on this task