Support arbitrary, temporary Entitlement grants#680
Conversation
…ntitlements (1 month cadence)
mitchelljkotler
left a comment
There was a problem hiding this comment.
I created another PR with SQL optimizations
| # Mirrors org.has_active_subscription() = bool(subscriptions.first()) | ||
| rule_clauses.append(Q(subscriptions__isnull=False)) | ||
|
|
||
| if rule_clauses: |
There was a problem hiding this comment.
Checking my understanding:
If you check require_verified then this entitlement grant applies to all Organizations which are verified (filtered by individual/group as appropriate)
If you check require_active_subscription then it applies to all Orgs with an active subscription (again filtered by individual/group)
If both are checked, then it applies to all Orgs which are both verified and have an active subscription.
| for clause in rule_clauses[1:]: | ||
| rule_q &= clause | ||
| return eligible.filter(explicit_q | rule_q).distinct() | ||
| return eligible.filter(explicit_q).distinct() |
There was a problem hiding this comment.
if there is only explicit_q then distinct is not necessary as you can't add the same org more than once.
| return self.name | ||
|
|
||
| def save(self, *args, **kwargs): | ||
| if self.update_on is None: |
There was a problem hiding this comment.
If you are just trying to set a default value, you can do this more cleanly by setting the default to a callable:
https://docs.djangoproject.com/en/6.0/ref/models/fields/#django.db.models.Field.default
| if not org.individual and not self.for_groups: | ||
| return False | ||
| # Uses `.all()` so a prefetched `organizations` relation is reused. | ||
| if any(o.pk == org.pk for o in self.organizations.all()): |
There was a problem hiding this comment.
if self.organizations.filter(pk=org.pk).exists():
|
|
||
| plan_q = Q(plans__organizations=org) | ||
| grant_pks = [g.pk for g in EntitlementGrant.objects.matching(org)] | ||
| grant_q = Q(grants__in=grant_pks) |
There was a problem hiding this comment.
This can be grant_q = Q(grants__in=EntitlementGrant.objects.matching(org))
Django will automatically use the PK if you pass in a model object
Fixes #666
Adds a new
EntitlementGrantmodel that lets us give Entitlements to Organizations.Previously, the only way to associate Entitlements with Organizations was through a Subscription to a Plan.
This allows us to grant access to resources in an arbitrary way to any org, and revoke them as needed, too.
This uses our same code path for refreshing entitlements on a monthly cadence.
This also updates our serializer to union entitlements, which will come in handy when we support multiple concurrent subscriptions.