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

add ability to create domain-scoped API keys #28493

Merged
merged 14 commits into from
Oct 8, 2020
Merged

add ability to create domain-scoped API keys #28493

merged 14 commits into from
Oct 8, 2020

Conversation

czue
Copy link
Member

@czue czue commented Sep 10, 2020

#28388

Had this almost done prior to 👶 and wanted to get it out before the 🕸️ get too dusty...

SUMMARY

This adds a new "domain" option to API keys to scope the key to only have permission for that domain. All existing keys will be assigned to the "all domains" scope.

Here's the UI:

image

FEATURE FLAG
RISK ASSESSMENT / QA PLAN

I feel good about test coverage and local testing, though it could make sense to do a dry run on staging. I may ask to hand that off if someone wants to make the case for it given life circumstance.

There is also a minor, innocuous DB migration.

PRODUCT DESCRIPTION

See screenshot.

@czue czue added the product/all-users-all-environments Change impacts all users on all environments label Sep 10, 2020
@czue
Copy link
Member Author

czue commented Sep 10, 2020

cc @dimagi/product

@czue czue added the reindex/migration Reindex or migration will be required during or before deploy label Sep 10, 2020
Copy link
Contributor

@snopoke snopoke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there still plans to allow selecting a role for the API key via the UI? As I see it that would also restrict an API key to a specific domain correct?

I imagine that you would want to have one or the other (role or domain) but not both.

@czue
Copy link
Member Author

czue commented Sep 10, 2020

Are there still plans to allow selecting a role for the API key via the UI? As I see it that would also restrict an API key to a specific domain correct?

I imagine that you would want to have one or the other (role or domain) but not both.

Yep this was planned. I was imagining a second dropdown, and then when you choose a domain you can also (optionally) choose a role, where the roles are dynamically pulled based the domain. But to do that in the UI was more than I could bite off before disappearing. Then I was thinking of adding an assertion in the model that if the role is set then the domain must match the role (or we could require only one is set if that seems preferable - though setting the domain makes it a bit easier in the django admin and other places)

@@ -3022,4 +3023,6 @@ def role(self):
return UserRole.get(self.role_id)
except ResourceNotFound:
logging.exception('no role with id %s found in domain %s' % (self.role_id, self.domain))
elif self.domain:
return CouchUser.from_django_user(self.user).get_domain_membership(self.domain).role
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When enterprise permissions are on, this will grant access to both their domain and any controlled domain (so, COVID state-level users will have access to all county domains). That's probably what you want, just wanted to confirm.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't consider this use case and don't know much about how the enterprise permissions work to have an opinion. Do you think it's the right behavior given the expectations of those roles as they're being used by the team?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think the current behavior matches what the team will expect.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having said that, I might as well verify that assumption. I'll report back if the current behavior is not what they expect.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you report back either way? Would feel better about having the loop closed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current code is the correct behavior.

super().__init__(*args, **kwargs)

user_domains = self.couch_user.get_domains()
all_domains = (self.ALL_DOMAINS, _('All Domains'))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: user-facing content usually says "project" or "project space" instead of "domain."

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch. be674a9

Comment on lines 307 to 315
if self.cleaned_data['domain'] and self.cleaned_data['domain'] != self.ALL_DOMAINS:
domain = self.cleaned_data['domain']
else:
domain = ''
new_key = HQApiKey.objects.create(
name=self.cleaned_data['name'],
ip_allowlist=self.cleaned_data['ip_allowlist'],
user=user,
domain=domain,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: if line 266 was changed to ALL_DOMAINS = '' could this be changed to

Suggested change
if self.cleaned_data['domain'] and self.cleaned_data['domain'] != self.ALL_DOMAINS:
domain = self.cleaned_data['domain']
else:
domain = ''
new_key = HQApiKey.objects.create(
name=self.cleaned_data['name'],
ip_allowlist=self.cleaned_data['ip_allowlist'],
user=user,
domain=domain,
new_key = HQApiKey.objects.create(
name=self.cleaned_data['name'],
ip_allowlist=self.cleaned_data['ip_allowlist'],
user=user,
domain=self.cleaned_data['domain'] or '',

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good call 09281b0

@nicknestle
Copy link

Is this going through QA? I'm nervous about our COVID projects being affected if this should go wrong given they all rely heavily on API integrations that cut across multiple domains. Is there a way we can confirm this won't break existing integrations and can we have a plan that when this is deployed we are able to actively monitor APIs in COVID domains to ensure nothing has gone wrong?

@kcowger
Copy link
Contributor

kcowger commented Sep 11, 2020

Is this going through QA? I'm nervous about our COVID projects being affected if this should go wrong given they all rely heavily on API integrations that cut across multiple domains. Is there a way we can confirm this won't break existing integrations and can we have a plan that when this is deployed we are able to actively monitor APIs in COVID domains to ensure nothing has gone wrong?

I'm seconding this. I think we should be careful around APIs given recent issues

@czue
Copy link
Member Author

czue commented Sep 12, 2020

Is this going through QA?

If we want to put this through QA, someone else will need to run that process as I'm on leave.

I'm nervous about our COVID projects being affected if this should go wrong given they all rely heavily on API integrations that cut across multiple domains. Is there a way we can confirm this won't break existing integrations and can we have a plan that when this is deployed we are able to actively monitor APIs in COVID domains to ensure nothing has gone wrong?

I have high confidence in the test coverage to catch any issues at the API access level. Monitoring on deploy sounds good as an extra precaution. My opinion is that this change is quite low risk (but happy for others to make the call to do more work to get more confidence)

@millerdev
Copy link
Contributor

@czue will a quick and easy rollback be possible if things go badly? Maybe it would make sense to split out the db migration into a separate PR (having ~no risk) from the API behavior change to make a rollback less risky?

@czue czue added the Open for review: do not merge A work in progress label Sep 15, 2020
@czue
Copy link
Member Author

czue commented Sep 15, 2020

@millerdev you're saying we merge and deploy the migration first, then deploy the UI and api changes separately so the latter can be rolled back if there are issues?

That sounds fine to me, though in a separate offline thread it sounds like the US team wants a more formal QA process to be run. Hopefully someone will be able to pick that up in my absence, else this PR might just get closed till I'm back in a few months. 😞

@Ben-Talbot
Copy link

Apologies all! My Github login is my personal gmail and I wasn't on the lookout for work related items with this email address. I'll update this so that going forward, these kind of messages will be in my work email.

Acknowledging that Cory will not be able to be the POC for any formal testing, I'd still be happy to take a pass on APIs on staging prior to release. We did something similar when Farid first unveiled the IP whitelist feature a few months back. When this is on staging, could someone please submit the QA request form (linked) and we can perform a review. Thanks all!

https://docs.google.com/forms/d/e/1FAIpQLSdSNi4r1UAenewXBvhL6qcDOfR9KnYYzFJBQd8uz6LOHW6ptg/viewform

@kaapstorm kaapstorm merged commit a52f934 into master Oct 8, 2020
@kaapstorm kaapstorm deleted the cz/role-ui branch October 8, 2020 14:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Open for review: do not merge A work in progress product/all-users-all-environments Change impacts all users on all environments reindex/migration Reindex or migration will be required during or before deploy
Projects
None yet
Development

Successfully merging this pull request may close these issues.