Skip to content

Support standard M2M scopes #483

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

Closed
maxceem opened this issue Feb 21, 2020 · 16 comments
Closed

Support standard M2M scopes #483

maxceem opened this issue Feb 21, 2020 · 16 comments
Milestone

Comments

@maxceem
Copy link
Contributor

maxceem commented Feb 21, 2020

@vikasrohit I've got a request from the James Cori to support standard M2M scopes:

  • all:project
  • read:project
  • write:project

Should we also keep the currently supported all:connect_project or can remove it?

Please, let me know if this task is good to proceed with or there are any decisions to make.

@vikasrohit
Copy link

we will analyze and prioritize it.

@vikasrohit vikasrohit added this to the Placeholder for 2.5 milestone Feb 21, 2020
@rootelement
Copy link

Hi @vikasrohit , we're entering dev test phase for about the next 3 weeks. I'd appreciate if we could get this implemented soon in dev, so the production push of this could go in step with the challenge v5 api launch slated for the end of March. I don't want v5 going live with the all:connect_project scope if possible.

@vikasrohit
Copy link

Sure @rootelement we will try to prioritize it.

@maxceem @rootelement can we add more details to what we expect (in terms of permissions) when these new scopes are associated with a m2m token? I mean all:project means all operations on all projects or all operations on the user's own projects. Similarly, write:project means updating only self (user is team member) projects or can update any project in system and so on. We need clear permission set for the scopes before we move ahead.

@vikasrohit vikasrohit modified the milestones: Placeholder for 2.5, 2.3 Mar 10, 2020
@maxceem
Copy link
Contributor Author

maxceem commented Mar 10, 2020

@vikasrohit as I understand M2M should get the same level of access as admin users, so:

  • read:project means reading all the data in Project Service (as admins can do)
  • write:project means being able to create, update and delete all the data in Project Service (as admins can do)
  • all:project combination of two above

@rootelement
Copy link

@maxceem is correct. This is a Machine to Machine token, so it will only be provisioned for our services to communicate. There's no "user" here. So what he has listed above is correct.

@maxceem
Copy link
Contributor Author

maxceem commented Mar 11, 2020

@vikasrohit should we keep support for the current scope all:connect_project? Or all the third party services which are using it now can update to a new all:project scope?

@vikasrohit
Copy link

Okay, thanks for the updates @maxceem and @rootelement

should we keep support for the current scope all:connect_project? Or all the third party services which are using it now can update to a new all:project scope?

That is something I was going to ask next. all:connect_project scope is used by other dependent services of Connect as well some of the POC projects ran around projects api. It might not be that difficult to update all tokens in other Connect services, however, there are potential issues that might arise even after updating all the permissions in m2m applications because caching of tokens. Even if we all agree on bear that pain for now, I think read:project/write:project/all:project scopes might conflict with existing scopes that we are using in direct projects api and we won't be able to separately configure permissions for legacy and v5 projects.
@rootelement if we are okay with bearing the pain of failing m2m services because of scope renaming of all:connect_project and are okay with controlling m2m permissions for both legacy (direct) and v5 projects via the same (or similar) scopes, we can go ahead with this requirement.

@maxceem
Copy link
Contributor Author

maxceem commented Apr 2, 2020

Make sure that we support M2M for inviting users and accepting an invitation, so we can add a member using these 2 calls using M2M:
create invite

curl 'https://api.topcoder-dev.com/v5/projects/8967/invites' \
   -H 'authorization: Bearer <ADMIN_TOKEN>' \
   -H 'content-type: application/json' \
   --data '{"handles":["maxceem"],"role":"customer"}'

accept the invite on behalf of the user

curl 'https://api.topcoder-dev.com/v5/projects/8967/invites/<inviteId>' \
   -X PATCH \
   -H 'authorization: Bearer <ADMIN_TOKEN>' \
   -H 'content-type: application/json' \
   --data '{"status":"accepted"}'

@maxceem
Copy link
Contributor Author

maxceem commented Apr 3, 2020

As per the clarification from James on Slack:

it’s better in the standard to use all:projects and update the direct stuff to use all:direct-project if possible. Stuff that is vestigial, i don’t mind it being out of the standard, but making a concession for a “connect-project” when it’s not….. i don’t like that. The actions aren’t for “connect” they’re for the project itself. The APIs need to be agnostic of what is using them going forward

We would not support all:connect_project which we support now, and would replace it with all:project along with adding read:project and write:project.

FYI @vikasrohit

@vikasrohit
Copy link

@maxceem lets create new scope all:projects along with all:connect_project because I am not sure who else is using that scope. At least our tc-message-service and salesforce connectors are using that scope for their m2m calls. We can get rid of that old scope once we identified all places where we are using it.

Also, for

Make sure that we support M2M for inviting users and accepting an invitation, so we can add a member using these 2 calls using M2M:

While this 2 calls based approach would also be okay, but I think when we are using the m2m, we can allow m2m callers to directly add members without any invite. We might create a special scope for handling this so that we know who all can add members to a project directly. Do you see any problem with that approach?

@maxceem
Copy link
Contributor Author

maxceem commented Apr 5, 2020

Do you see any problem with that approach?

No, it looks good to me.

We might create a special scope for handling this so that we know who all can add members to a project directly.

Should it be *:project-members? (i. e. all:project-members, write:project-members, read:project-members). Though it would create kind of confusion: on the one hand, we don't need read:project-members to view projects members, as we return them together with projects. On the other hand, we need write:project-members to create them.

Should we also let Topcoder Admins add any member directly? or only for M2M?

@vikasrohit
Copy link

I think we have to create separate scopes for separate resources, I guess and project member is a separate resource. Even thought it is returned right now with read:project, it is logical add read:project-members and return them only when the calling m2m token has both read:project and read:project-members scopes. We can even introduce read:invites and write:invites for the similar operations on Invites. I know it might cause a bit more work, hence, I am okay with read:project returning all sub resources for now, but we can keep a separate issue for tracking the concerned I shared and implement it later. On the other hand, if that scoping for sub resources (for now only members and invites) is not a too much ask, I would prefer getting it done with this issue.
@maxceem let me know how do you see the time line for both the cases.

@maxceem
Copy link
Contributor Author

maxceem commented Apr 6, 2020

@vikasrohit from the comments 1 and 2 it looks like for the scope we are going to support several namespaces with granular permissions for some operations, so I think the best approach would be to extend our general method for checking permissions to also support scope for M2M tokens like this:

MANAGE_TOPCODER_TEAM_INVITES: {
   projectRoles: ['manager', 'account_manager'],
   topcoderRoles: ['administrator', 'Connect Manager'],
   scopes: ['all:project', 'write:project']
 }

PS: I've just got your new comment. Will think about it...

@maxceem
Copy link
Contributor Author

maxceem commented Apr 6, 2020

Even thought it is returned right now with read:project, it is logical add read:project-members and return them only when the calling m2m token has both read:project and read:project-members scopes.

I only have concerns regarding requiring both scopes. What if we require only one scope per resource?

  • If we GET /project/{id} with read:project project is returned but without members
  • If we GET /project/{id} with read:project-members request fails
  • If we GET /project/{id} with both read:project read:project-members project is returned with members
  • if we GET /project/{id}/members with read:project-members members are returned
  • if we GET /project/{id}/members with read:project request fails

So for each resource, we need a scope. But we don't require 2 scopes for getting one resource.

What do you think about such an approach?

@vikasrohit
Copy link

@maxceem I didn't find difference between my suggested scopes and your one... in other words, I think what you have written down is the same what I have in my mind.

If we GET /project/{id} with both read:project read:project-members project is returned with members

@maxceem
Copy link
Contributor Author

maxceem commented Apr 28, 2020

This has been implemented for 3 sets of endpoints via #555 and available at DEV environment.

Projects:

  • POST /projects
  • GET /projects
  • GET /projects/{projectId
  • PATCH /projects/{projectId}
  • DELETE /projects/{projectId}

scopes: all:projects, read:projects, write:projects

Projects Members:

  • POST /projects/{projectId}/members
  • GET /projects/{projectId}/members
  • GET /projects/{projectId}/members/{id}
  • PATCH /projects/{projectId}/members/{id}
  • DELETE /projects/{projectId}/members/{id}

scopes: all:project-members, read:project-members, write:project-members

Projects Members Invites:

  • POST /projects/{projectId}/invites
  • GET /projects/{projectId}/invites
  • GET /projects/{projectId}/invites/{id}
  • PATCH /projects/{projectId}/invites/{id}
  • DELETE /projects/{projectId}/invites/{id}

scopes: all:project-members, read:project-members, write:project-members

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

3 participants