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

enroll non-UMich users (iss. #221, #169, #252, #291) #247

Merged
merged 166 commits into from
Feb 24, 2022

Conversation

lsloan
Copy link
Member

@lsloan lsloan commented Nov 18, 2021

Resolves #221.

As well as…

Resolves #169.
Resolves #252.
Resolves #291.

PR review etiquette requests

To my reviewer friends, I humbly request…

  • When making comments about the PR, especially ones requesting changes, please use the "code review" form of comments, not "single comment". The review style ones allow for direct replies which make threaded, easier to follow conversations. The single comments do not.
  • If you make a review comment requesting that I change something, when I've completed the change (or made a comment reply), I will reply with "🏁" or "✅" when I think the conversation has been resolved. As the reviewer, I will leave it up to you to decide whether the conversation needs to continue or it's time to click the "Resolve conversation" button.

To Do

Older to do items (click to expand)
  • - Resolve build error.
  • - Verify user info as admin function appears in Swagger API UI
  • - user info as admin (/api/admin/user/:loginId) function may cause an error
    • @pushyamig reported trouble with this function. InvalidTokenInterceptor may need to be removed from this route, and possibly others that use admin token. The user’s token shouldn’t be deleted in this case.
    • See conversation in Slack.
  • - Change response structure.
    • Rather than return all account creations together, all invitations together, and all enrollments together in keys specifically for those, organize it by user. A key for each user ID requested, each of which contains keys for their account creation, invitation, and enrollment.
    • This is to remove the need to parse through the data in the UI.
    • @ssciolla made significant contributions to this to help with a TS problem and to make further changes to the response structure. See f350a78.
  • - Replace invitation service Axios calls with NestJS HttpModule calls
  • - Role type checking. I.e., @IsIn decorator for enrollment type in DTO
  • - Move checks for allowed roles from the service level to controller level
  • - Package lockfile changes
    • See @ssciolla's comment and my earlier acknowledgement.
    • Changes here depend on whether changes from Axios to HttpModule are successful and whether HttpModule request should utilize FormData.
  • - Remove enrollment step, leaving only creation and invitation
    • Based on Slack conversation in which @ssciolla wrote…

      Right now, I’m toying with the idea of splitting up the backend process into two processes: 1) creating a user/sending a Cirrus invitation and 2) enrolling the user in the section. This would allow us to selectively apply the interceptor to the correct calls. The process for 2 already exists.

    • API entry should be at admin/createExternalUsers.
  • - Change tense/wording of steps in external user enrollment API response
    • Based on Slack conversation in which @ssciolla wrote…

      I was thinking we may to make the tense/wording the same for each of these steps too. So, userCreation, invitation, enrollment, or userCreated, invited, enrolled

  • - Remove Swagger link changes

Very simplistic approach for now.  Should be refactored to reduce duplication of code before merging upstream.
@lsloan lsloan self-assigned this Nov 18, 2021
@lsloan lsloan changed the title enroll non-UMich (iss. #221) 🚧 DRAFT: enroll non-UMich users (iss. #221) Nov 18, 2021
Also, temporarily accept results as JSON string.  Method based on one for enrolling existing users
Temporarily use JSON results as return value.
Comment on lines 29 to 31
const invitationConfig = configService.get('invitation', { infer: true })
const apiURL = invitationConfig.apiURL
this.url = apiURL + cirrusAPIVersion + CirrusAPIEndPoint
Copy link
Contributor

Choose a reason for hiding this comment

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

Codacy says this is an issue, but I don't think it is. I believe Codacy doesn't have access to typing from NestJS, so it can't determine the type of apiURL. Anywho, you can ignore this issue in Codacy. Click on the settings icon dropdown on the issue in the Codacy UI, then click "Ignore Issue".

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for the advice on ignoring. I didn't try that, but I had tried to change the code pattern config. That didn't work because Codacy said it was using the config file from our repo. I didn't think it'd be wise for me to change that config just to placate Codacy. At least, not without discussing it with you and the team first. That might mask real errors, I'd guess.


return response.data
} catch (error) {
if (axios.isAxiosError(error) && error.response !== undefined) {
Copy link
Contributor

@ssciolla ssciolla Feb 24, 2022

Choose a reason for hiding this comment

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

Similar deal here. Codacy doesn't have access to the axios typing, so I think Codacy believes error and response are any. You can safely ignore the issue in Codacy.

Comment on lines +58 to +61
INVITATION_API_URL=https://apps.cirrusidentity.com/console
INVITATION_API_KEY=
INVITATION_API_SECRET=
INVITATION_API_ENTITY_ID=
Copy link
Contributor

Choose a reason for hiding this comment

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

These may benefit from short comment descriptions.

lsloan and others added 2 commits February 24, 2022 11:25
correct case from @pushyami's code

Co-authored-by: Sam Sciolla <35741256+ssciolla@users.noreply.github.com>
Checking for specific error indicators among the long error body returned by Canvas.
@lsloan
Copy link
Member Author

lsloan commented Feb 24, 2022

As @pushyamig requested, I've done some testing.

I've run several, at least ten or more, requests containing 200 semi-randomly generated users. Each time…

  • all 200 are created as new users in Canvas
  • all 200 are accepted by Cirrus for invitation and appear in their console
  • random spot-checking shows each has received an email message

These batches of 200 take a range of 8–13 seconds to complete.

Batches with more than 200 users gets an HTTP 400 error with the message…

{"statusCode":400,"message":["users must contain not more than 200 elements"],"error":"Bad Request"}

Copy link
Contributor

@ssciolla ssciolla left a comment

Choose a reason for hiding this comment

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

Releasing comments now. There is a compilation error; @lsloan, you need to update references to cirrusPIEndpoint. Not seeing any (other) super serious issues. I'll finish the review with testing now.

Comment on lines +135 to +137
21. Copy the static API key created in Canvas. The ID is the long number shown
in the "Details" column of the "Developer Keys" page. It usually begins
with "1770~…".
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this still accurate? I would think you'd do this in Settings, not anything related to Developer Keys.

7. Add to the `CANVAS_ADMIN_API_TOKEN` key the API token copied earlier
(in step 20).
8. Configure invitation API settings. The invitation API used by CCM is
currently based on Cirrus Identity services. Provide values for each
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe for now just link "Cirrus Identity service" to the Cirrus site.

): Promise<Array<{ result: CanvasUserLoginEmail | APIErrorData | false, email: string }>> {
const start = process.hrtime.bigint()

// Try creating all Canvas users; failure often means user already exists
Copy link
Contributor

Choose a reason for hiding this comment

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

This comment may no longer be exactly accurate, since we're handling the unique ID error internally and returning false.

ccm_web/server/src/api/api.admin.handler.ts Show resolved Hide resolved
@@ -103,6 +134,16 @@ export class APIController {
return enrollmentsResult
}

// Do NOT use `InvalidTokenInterceptor` here!
Copy link
Contributor

Choose a reason for hiding this comment

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

Could just remove this, or if you want to have something, maybe say something like // Uses admin token, so InvalidTokenInterceptor omitted. If you do keep it, please add something to the other endpoint,admin/createExternalUsers.

Copy link
Member Author

Choose a reason for hiding this comment

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

🏁

ccm_web/server/src/api/api.utils.ts Outdated Show resolved Hide resolved
ccm_web/server/src/api/api.utils.ts Show resolved Hide resolved
ccm_web/server/src/canvas/canvas.interfaces.ts Outdated Show resolved Hide resolved
ccm_web/server/src/invitation/cirrus-invitation.service.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@ssciolla ssciolla left a comment

Choose a reason for hiding this comment

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

@lsloan, okay, I've done some testing, and I think we're in good shape. I would give approval, but the compilation error hasn't been fixed. I also think it would be a good improvement to tighten and simplify the CanvasUser interface(s) as described in my latest comments. I will keep an eye on these and give an approval as soon as these two things are taken care of. Everything else is minor and can be resolved as you see fit. Let's finish this!

ccm_web/server/src/canvas/canvas.interfaces.ts Outdated Show resolved Hide resolved
ccm_web/server/src/api/api.admin.handler.ts Outdated Show resolved Hide resolved
ccm_web/server/src/canvas/canvas.interfaces.ts Outdated Show resolved Hide resolved
…into 221-enroll-non-umich

* '221-enroll-non-umich' of https://github.com/lsloan/ccm:
  check for unique ID error during Canvas user creation (#7)
  Update ccm_web/server/src/invitation/cirrus-invitation.interfaces.ts
I didn't fix refs after accepting change suggestion in GH PR.  I also hadn't pulled from GH, so I didn't see the compile errors this had caused.
I didn't fix refs after accepting change suggestion in GH PR.  I also hadn't pulled from GH, so I didn't see the compile errors this had caused.  (EDIT: Updated to use Pushyami's correct username, "pushyamig".  Apologies to @pushyami.  I wish I could easily go back to correct the other commit message, too.)
@lsloan

This comment was marked as outdated.

@lsloan

This comment was marked as outdated.

@ssciolla

This comment was marked as resolved.

@lsloan
Copy link
Member Author

lsloan commented Feb 24, 2022

@ssciolla wrote in #247 (comment):

Actually, login_id also seems to be present in both cases. Could we just add login_id to CanvasUser, then delete CanvasUserLoginEmail and replace all references to it with CanvasUser?

Yes, I think so. I'll give it a go.

I take that back. As I'm trying to change CanvasUserLoginEmailCanvasUser everywhere, that turns out to be a problem because CanvasUser doesn't include email. I guess I could add email to it, as I've just done with login_id. I don't know whether that will still be compatible with results returned by the Canvas API.

Is that what you'd like?

Thanks for working that through with me in Zoom. As you went along, I think you ended up with an even better solution than you anticipated.

Copy link
Contributor

@ssciolla ssciolla left a comment

Choose a reason for hiding this comment

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

I'm approving. Thanks @lsloan for being flexible as we changed some of the architecture choices, and for considering my PR requests to your branch. There are some comments and suggestions still pending, but none of them seem serious enough to prevent merging or require additional review from me. Please resolve them as you see fit.

@pushyamig, you may want to take a look, for your general awareness, at some of the logic and error handling changes we made -- I'm thinking particularly of api.service.ts, canvas.interfaces.ts and api.utils.ts.

@lsloan
Copy link
Member Author

lsloan commented Feb 24, 2022

Thanks for approving the PR, @ssciolla. I'm glad to see this PR near its end.

I feel my involvement in CCM has aged me significantly.

rapid aging

@lsloan lsloan changed the title enroll non-UMich users (iss. #221, #252, #291) enroll non-UMich users (iss. #221, #169, #252, #291) Feb 24, 2022
@lsloan lsloan merged commit 8d55aa8 into tl-its-umich-edu:main Feb 24, 2022
@lsloan lsloan deleted the 221-enroll-non-umich branch February 24, 2022 21:41
lsloan added a commit to lsloan/ccm that referenced this pull request Mar 24, 2022
Apparently I'd forgotten to commit this doc change.
pushyamig pushed a commit that referenced this pull request Apr 8, 2022
Apparently I'd forgotten to commit this doc change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API config change Involves a change to the configuration file/format enhancement New feature or request
Projects
None yet
3 participants