Creates the initial user for a Coder deployment. @Summary Create initial user @ID create-initial-user @Security CoderSessionToken @Accept json @Produce json @Tags Users @Param request body codersdk.CreateFirstUserRequest true "First user request" @Success 201 {object} codersdk.CreateFirstUserRespon
(rw http.ResponseWriter, r *http.Request)
| 175 | // @Success 201 {object} codersdk.CreateFirstUserResponse |
| 176 | // @Router /api/v2/users/first [post] |
| 177 | func (api *API) postFirstUser(rw http.ResponseWriter, r *http.Request) { |
| 178 | // The first user can also be created via oidc, so if making changes to the flow, |
| 179 | // ensure that the oidc flow is also updated. |
| 180 | ctx := r.Context() |
| 181 | var createUser codersdk.CreateFirstUserRequest |
| 182 | if !httpapi.Read(ctx, rw, r, &createUser) { |
| 183 | return |
| 184 | } |
| 185 | |
| 186 | // This should only function for the first user. |
| 187 | // nolint:gocritic // Getting user count is a system function. |
| 188 | userCount, err := api.Database.GetUserCount(dbauthz.AsSystemRestricted(ctx), false) |
| 189 | if err != nil { |
| 190 | httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ |
| 191 | Message: "Internal error fetching user count.", |
| 192 | Detail: err.Error(), |
| 193 | }) |
| 194 | return |
| 195 | } |
| 196 | |
| 197 | // If a user already exists, the initial admin user no longer can be created. |
| 198 | if userCount != 0 { |
| 199 | httpapi.Write(ctx, rw, http.StatusConflict, codersdk.Response{ |
| 200 | Message: "The initial user has already been created.", |
| 201 | }) |
| 202 | return |
| 203 | } |
| 204 | |
| 205 | err = userpassword.Validate(createUser.Password) |
| 206 | if err != nil { |
| 207 | httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ |
| 208 | Message: "Password is invalid", |
| 209 | Validations: []codersdk.ValidationError{{ |
| 210 | Field: "password", |
| 211 | Detail: err.Error(), |
| 212 | }}, |
| 213 | }) |
| 214 | return |
| 215 | } |
| 216 | |
| 217 | if createUser.Trial && api.TrialGenerator != nil { |
| 218 | err = api.TrialGenerator(ctx, codersdk.LicensorTrialRequest{ |
| 219 | Email: createUser.Email, |
| 220 | FirstName: createUser.TrialInfo.FirstName, |
| 221 | LastName: createUser.TrialInfo.LastName, |
| 222 | PhoneNumber: createUser.TrialInfo.PhoneNumber, |
| 223 | JobTitle: createUser.TrialInfo.JobTitle, |
| 224 | CompanyName: createUser.TrialInfo.CompanyName, |
| 225 | Country: createUser.TrialInfo.Country, |
| 226 | Developers: createUser.TrialInfo.Developers, |
| 227 | }) |
| 228 | if err != nil { |
| 229 | httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ |
| 230 | Message: "Failed to generate trial", |
| 231 | Detail: err.Error(), |
| 232 | }) |
| 233 | return |
| 234 | } |
nothing calls this directly
no test coverage detected