postConvertLoginType replies with an oauth state token capable of converting the user to an oauth user. @Summary Convert user from password to oauth authentication @ID convert-user-from-password-to-oauth-authentication @Security CoderSessionToken @Accept json @Produce json @Tags Authorization @Para
(rw http.ResponseWriter, r *http.Request)
| 89 | // @Success 201 {object} codersdk.OAuthConversionResponse |
| 90 | // @Router /api/v2/users/{user}/convert-login [post] |
| 91 | func (api *API) postConvertLoginType(rw http.ResponseWriter, r *http.Request) { |
| 92 | var ( |
| 93 | user = httpmw.UserParam(r) |
| 94 | ctx = r.Context() |
| 95 | auditor = api.Auditor.Load() |
| 96 | aReq, commitAudit = audit.InitRequest[database.AuditOAuthConvertState](rw, &audit.RequestParams{ |
| 97 | Audit: *auditor, |
| 98 | Log: api.Logger, |
| 99 | Request: r, |
| 100 | Action: database.AuditActionCreate, |
| 101 | }) |
| 102 | ) |
| 103 | aReq.Old = database.AuditOAuthConvertState{} |
| 104 | defer commitAudit() |
| 105 | |
| 106 | var req codersdk.ConvertLoginRequest |
| 107 | if !httpapi.Read(ctx, rw, r, &req) { |
| 108 | return |
| 109 | } |
| 110 | |
| 111 | switch req.ToType { |
| 112 | case codersdk.LoginTypeGithub, codersdk.LoginTypeOIDC: |
| 113 | // Allowed! |
| 114 | case codersdk.LoginTypeNone, codersdk.LoginTypePassword, codersdk.LoginTypeToken: |
| 115 | // These login types are not allowed to be converted to at this time. |
| 116 | httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ |
| 117 | Message: fmt.Sprintf("Cannot convert to login type %q.", req.ToType), |
| 118 | }) |
| 119 | return |
| 120 | default: |
| 121 | httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ |
| 122 | Message: fmt.Sprintf("Unknown login type %q.", req.ToType), |
| 123 | }) |
| 124 | return |
| 125 | } |
| 126 | |
| 127 | // This handles the email/pass checking. |
| 128 | user, _, ok := api.loginRequest(ctx, rw, codersdk.LoginWithPasswordRequest{ |
| 129 | Email: user.Email, |
| 130 | Password: req.Password, |
| 131 | }) |
| 132 | if !ok { |
| 133 | return |
| 134 | } |
| 135 | |
| 136 | // Only support converting from password auth. |
| 137 | if user.LoginType != database.LoginTypePassword { |
| 138 | // This is checked in loginRequest, but checked again here in case that shared |
| 139 | // function changes its checks. Just some defensive programming. |
| 140 | // This login type is **required** to be password based to prevent |
| 141 | // users from converting other login types to OIDC. |
| 142 | httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ |
| 143 | Message: "User account must have password based authentication.", |
| 144 | }) |
| 145 | return |
| 146 | } |
| 147 | |
| 148 | stateString, err := cryptorand.String(32) |
nothing calls this directly
no test coverage detected