Skip to content
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

Support ToMany in PrincipalsMixin #95

Open
odcinek opened this issue Aug 12, 2016 · 6 comments
Open

Support ToMany in PrincipalsMixin #95

odcinek opened this issue Aug 12, 2016 · 6 comments

Comments

@odcinek
Copy link

odcinek commented Aug 12, 2016

PrincipalsMixin seems to support ToOne fields, but ToMany is left unimplemented . I haven't found a good way to express it in flask-principal terms, without creating a Need instance for every relation member.

@lyschoening How would you approach this? Happy to take a shot at implementing this.

@lyschoening
Copy link
Contributor

Ah, I left this out when I implemented this because I could not think of any immediate use case.
Frankly, I still cannot think of any. Permissions are usually set up in a tree structure. Do you have an example scenario?

Regarding the implementation: If we say that "any" of the items in the relationship needs to fulfil the need, then it might be enough to replace isinstance(field, ToOne) with isinstance(field, (ToOne, ToMany)). When the query is built, PrincipalsMixin calls SQLAlchemyManager._expression_for_join(), which will automatically determine the correct join to use.

It is possible that I am overlooking something. It would definitely need some tests. Since I unwisely wrote all the tests against a single database model it might also be necessary to add a new TestCase.

@goshasawicka
Copy link

Hi. One of the examples might be a user who is a member of a group.
Case scenario: Restrict updates on Group resource to its members according to the model below.

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(120), unique=True)
    group_id = db.Column(db.Integer, db.ForeignKey('group.id'))

class Group (db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(140))
    members = db.relationship('User', backref='group')

@odcinek
Copy link
Author

odcinek commented Aug 12, 2016

@lyschoening I managed to make it work, I'll send a PR once I figure the tests

@lyschoening
Copy link
Contributor

@odcinek Ok, thanks for doing this!

@Patyk That makes sense. Please note, if it is only a handful of group memberships I would recommend fetching them as ItemNeed when the identity is loaded.

@jas32096
Copy link
Contributor

@odcinek Any update on your progress? I'd like to use this in my own project

@galuszkak
Copy link

I think I have really similar use case here. @odcinek @Patyk did you manage to create something for this, or maybe you can share Your solution for that problem? I will greatly appreciate any insights on that :).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants