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

Sync will invite, uninvited, remove and ignore users #47

Closed
wants to merge 6 commits into from

Conversation

huwr
Copy link
Member

@huwr huwr commented Apr 3, 2020

Previously, we were only looking at the users list, and inviting people who were not on it. This causes trouble when run twice. If we had invited someone, but they have not yet accepted their invitation, the code would attempt to invite them again. That is not allowed by the API. It would return an error and the program would end.

The reason the code would attempt to invite them twice is because it only checked the Users API endpoint. It also needed to check the Pending Invitations to see who has been invited.

Now, we look at not only who is in the users list, but also who has been invited. This means you can run the program many times with the same list, and it will have the same effect. A user who has already invited won't be invited a second time.

For everyone in the input list, we check if they are in either the existing users or the invited users lists. If they are, we can ignore that entry. If they are not, we invite them.

For everyone in the existing users list that we want to remove, there are two things we might have to do: remove them from the users list, or remove them from the invited users list. Since the users and invited users are separate API calls there are two separate operations for deleting users or uninviting them.

This does everything in #5 except for modification. If a user in the input file has a role that they do not have in the API, we should be adding that role.

📝 Summary of Changes

Changes proposed in this pull request:

  • Make sync remove and ignore invitations

⚠️ Items of Note

Please don't do this on the IBA users list. 👍

🧐🗒 Reviewer Notes

💁 Example

Say this is our current user list:

User email Accepted Invation?
Carol [email protected] true
Edith [email protected] false
Fran [email protected] true

We wish to remove Edith, who never accepted the invitation, and Fran, who no longer works here.

Start by grabbing all my existing users. We'll use this as our input file:

./appstoreconnect-cli users list --output-format json > users.json

I'll add Alice, Bob and Dave to users.json, and remove Edith and Fran.

./appstoreconnect-cli users sync --input-format json users.json
invited [email protected]
invited [email protected]
ignored [email protected]
invited [email protected]
uninvited [email protected]
removed [email protected]

If I run that a second, third, or fourth time it becomes:

./appstoreconnect-cli users sync --input-format json users.json
ignored [email protected]
ignored [email protected]
ignored [email protected]
ignored [email protected]

All the entries are now ignored. They already exist as users or have pending invitations.

🔨 How To Test

Please do not do this on IBA's users list. I recommend doing it on your own App Store Connect account. Remember uninviting and removing are separate operations.

huwr added 2 commits April 3, 2020 13:56
It doesn't need to throw. Don't do it.
Previously, we were only looking at the users list, and inviting people who were not on it. This causes trouble when run twice. If we had invited someone, but they have not yet accepted their invitation, the code would attempt to invite them again. That is not allowed by the API. It would return an error and the program would end.

Now, we look at not only who is in the users list, but also who has been invited. This has made the 'diffing' code a lot more complex, but it allows us to compare across two lists.

For everyone in the input list, we check if they are in either the existing users and invited users lists. If they are there, we can ignore that entry. If they are not, we can invite them.

For everyone in the existing users list that we want to remove, there are two things we might have to do: remove them from the users list, or remove them from the invited users list. Since the users and invited users are separate API calls there are two separate operations for deleting users or uninviting them.
@huwr huwr added the enhancement New feature or request label Apr 3, 2020
@huwr huwr requested review from orj, adamjcampbell and DechengMa April 3, 2020 03:18
@huwr huwr self-assigned this Apr 3, 2020
@DechengMa
Copy link
Contributor

LGTM! Just realize that we can also have another PR for a reinviting user feature: if an invitation get expired, or that user missed the invitation email, we can reinvite them by

  1. cancel their invitation,
  2. and send the invitation again

It's might be in a different PR I think

@huwr
Copy link
Member Author

huwr commented Apr 3, 2020

Yeah! I think the reinvite one might be a different PR. Quite easy to do. I can give it a shot this afternoon.

print("+\(user.username)")
case .remove(_, let user, _):
print("-\(user.username)")
case .ignore(let username):
Copy link
Member

Choose a reason for hiding this comment

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

There is probably a better way of formatting this input but I can't think of anything right now.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is the output from the sync command. It's called input here in conformance with the Renderer protocol.

You're right that there should be a better a way of showing it, but I didn't get up to that. Originally, I had this rendering with + for users added, and - for users removed. I did that because I wanted it to look like a diff. That didn't stand up when I wanted seperate output for removing users and rescinding invitations.

return client
.request(APIEndpoint.invite(user: user))
.map { _ in change }
.map { _ in operation }
Copy link
Member

Choose a reason for hiding this comment

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

🧐 I don't like this very much. Seems real side-effecty. Ie, the only thing we actually want here is the side effect and then we're mapping it to the input.

Copy link
Member Author

Choose a reason for hiding this comment

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

You're right! These effects should be done in the receiveValue function right at the end of the whole thing. That would feel better, in my opinion.


private func invitationsInAppStoreConnect(_ client: HTTPClient) -> AnyPublisher<[UserInvitation], Error> {
client
.request(.invitedUsers())
Copy link
Member

Choose a reason for hiding this comment

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

Will this include expired invitations? Users with expired invitations should be re-invited.

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 test that! As far as I am aware it will not include them in this list, and will therefore re-invite them. This will need to be explored, though

Copy link
Contributor

@DechengMa DechengMa Apr 6, 2020

Choose a reason for hiding this comment

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

I remember it is needed to cancel an invitation before reinvite, even it's an expired invitation. otherwise, it will show an error

@orj orj assigned orj and unassigned huwr Apr 8, 2020
@orj
Copy link
Member

orj commented May 1, 2020

Sorry @huwr, gonna close this and look at it again in future.

@orj orj closed this May 1, 2020
@orj orj deleted the huwr/sync-removes-now branch May 1, 2020 01:31
@huwr
Copy link
Member Author

huwr commented May 3, 2020 via email

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

Successfully merging this pull request may close these issues.

3 participants