-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
ARCH-135 Add new custom DOT Application model to support OAuth2 per-application scopes. #18416
Conversation
bb12ba3
to
bf3202b
Compare
94a3008
to
8840b0e
Compare
@edx/devops Heads up! Migration coming through. |
8840b0e
to
f299de3
Compare
] | ||
|
||
operations = [ | ||
migrations.RunPython(migrate_application_data), |
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.
Questions about this migration:
- Can we pass
reverse_code=RunPython.noop
to be explicit that there's no rollback of this migration? - What happens if the migration is run, rolled back, and then re-run? Will
migrate_application_data
handle that? - What if
migrate_application_data
fails in the middle? Will re-running the migration coalesce any issues? - How will we prevent or detect that no new
Application
entries get created in between this PR and the one that changessettings.OAUTH2_PROVIDER_APPLICATION_MODEL
? Should we create another small PR that changes the value ofsettings.OAUTH2_PROVIDER_APPLICATION_MODEL
? Should we move this migration to a management command that runs again (just in case)?
#2 and #3 are all issues that have actually happened in production, so not just theoretical.
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.
- Done.
2+3. Switched toget_or_create
instead ofsave
. - We should accept that risk. We can do a manual check after we switch to the new application model to verify that the two application tables are in sync.
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.
@feanil FYI on this migration strategy.
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.
Adding:
5. The "id" field in the new and old Application models need to match exactly in order to support all previously created tokens/grants/etc. Those tables have foreign keys to the Application table via the "id" field.
scopes = ListCharField( | ||
base_field=models.CharField(max_length=32), | ||
size=10, | ||
max_length=(10 * 33), # 10 * 32 character scopes, plus commas |
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.
Where does this number come from? From the RFC?
default=CONTENT_PROVIDER_TYPE, | ||
) | ||
application = models.ForeignKey( | ||
oauth2_settings.APPLICATION_MODEL, |
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.
Should this be dependent on the setting - or always related to ScopedApplication
since they seem to be sister models? Each way has its own trade-offs, of course. I suppose the current way is more extensible, right?
What if someone changes the setting? That won't result in a new migration. But that should be Ok, I believe.
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.
Yes, I think this is good as is.
@@ -0,0 +1,9 @@ | |||
""" |
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.
Nit: These are unused in this PR at the moment.
scopes = ListCharField( | ||
base_field=models.CharField(max_length=32), | ||
size=10, | ||
max_length=(10 * 33), # 10 * 32 character scopes, plus commas |
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.
Where does this number come from? From the RFC?
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 didn't see any specification of size limits in the RFC. This was copied over from the original Microsoft PR. Did you have a different number in mind?
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.
@mettursathish Is there a reason your team chose this limit?
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.
Bumping this from 10 to 25 as discussed on Slack#architecture.
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 specific reason why we chose 10.
f299de3
to
0c228be
Compare
@@ -46,6 +46,7 @@ django-memcached-hashring | |||
django-method-override==0.1.0 | |||
django-model-utils==3.0.0 | |||
django-mptt>=0.8.6,<0.9 | |||
django-mysql |
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.
Is this new dependency still needed?
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.
Yes, I'm using this for the list of strings filed that stores the scopes on ScopedApplication
.
6118adc
to
cbfa5fd
Compare
61b3b43
to
a4f9f67
Compare
ScopedApplication = apps.get_model('oauth_dispatch', 'ScopedApplication') | ||
|
||
for application in Application.objects.all(): | ||
ScopedApplication.objects.get_or_create( |
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.
Would it make sense to use update_or_create instead?
] | ||
|
||
operations = [ | ||
migrations.RunPython(migrate_application_data, reverse_code=migrations.RunPython.noop), |
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 think you may actually want to implement a proper reverse here because if we end up making changes to the new table, we will probably want to propagate them back to the old table so auth does not break. This is an unlikely case but I'd rather have it implemented correctly if we need it.
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 won't need it. The new table will not be accessible from the app until we are certain we won't be rolling back.
a4f9f67
to
bd3db55
Compare
id = models.IntegerField(primary_key=True) | ||
scopes = ListCharField( | ||
base_field=models.CharField(max_length=32), | ||
size=10, |
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 also needs to update to 25 (to be consistent with max_length
.
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.
Good catch.
…n scopes. This also introduces a model for persisting organization-based filters on a per-application basis. See openedx/core/djangoapps/oauth_dispatch/docs/decisions/0007-include-organizations-in-tokens.rst for additional details.
bd3db55
to
bab6e36
Compare
Your PR has finished running tests. There were no failures. |
EdX Release Notice: This PR has been deployed to the staging environment in preparation for a release to production on Thursday, June 21, 2018. |
EdX Release Notice: This PR has been deployed to the production environment. |
ARCH-135
Add new custom DOT Application model to support OAuth2 per-application scopes.
This also introduces a model for persisting organization-based filters on
a per-application basis. See openedx/core/djangoapps/oauth_dispatch/docs/decisions/0007-include-organizations-in-tokens.rst
for additional details.