/// <summary> /// Registers a new user in Auth0 and assigns it the role 'Student'. /// </summary> /// <exception cref="ArgumentNullException"/> /// <exception cref="ArgumentException">Email or password is missing</exception> /// <exception cref="ApiException">Auth0 reported an error during registration</exception> public static async Task <string> CreateUserAsync(UserRegistrationArgs args) { if (args == null) { throw new ArgumentNullException(nameof(args)); } if (string.IsNullOrEmpty(args.Email)) { throw new ArgumentException("Email is required", nameof(args)); } if (string.IsNullOrEmpty(args.Password)) { throw new ArgumentException("Password is required", nameof(args)); } var accessToken = await GetAccessTokenAsync(); var management = new ManagementApiClient(accessToken, _authConfig.Domain); var user = await management.Users.CreateAsync(new UserCreateRequest { Email = args.Email, FirstName = args.FirstName, LastName = args.LastName, FullName = string.Join(' ', args.FirstName.Trim() ?? "", args.LastName.Trim() ?? ""), Password = args.Password, AppMetadata = new { roles = new[] { UserRoles.Student.ToString() } }, Connection = "Username-Password-Authentication" // TODO: Make configurable }); return(user.UserId); }
[ProducesResponseType(409)] // User with same email already exists public async Task <IActionResult> RegisterAsync([FromBody] UserRegistrationArgs args) { if (!ModelState.IsValid) { return(BadRequest(ModelState)); } if (_userIndex.IsEmailInUse(args.Email)) { return(StatusCode(409, new { Message = $"A user with email address '{args.Email}' already exists" })); } try { // Step 1) Register user in Auth0 var userId = await Auth.CreateUserAsync(args); try { // Step 2) Register user in UserStore var userArgs = new UserEventArgs { UserId = userId, Email = args.Email, FirstName = args.FirstName, LastName = args.LastName }; var id = _entityIndex.NextId(ResourceTypes.User); await EntityManager.CreateEntityAsync(_eventStore, userArgs, ResourceTypes.User, id, User.Identity.GetUserIdentity()); return(Created($"{Request.Scheme}://{Request.Host}/api/Users/{userId}", userId)); } catch (Exception e) { _logger.LogError(e, $"A new user with email address '{args.Email}' was registered in Auth0, but could not " + $"be registered in UserStore. Users are now inconsistent/out of sync. To solve this, " + $"delete the user in Auth0."); throw; // In this case "500 Internal Server Error" is appropiate } } catch (ApiException e) { return(StatusCode(e.ApiError.StatusCode, e.ApiError.Message)); } }