/// <summary> /// <inheritdoc /> /// </summary> /// <param name="model"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public virtual async Task <User> GoogleLoginAsync(GoogleLoginViewModel model, CancellationToken cancellationToken = default(CancellationToken)) { // Get the profile information. var profile = await _externalAuthenticationService.GetGoogleBasicProfileAsync(model.IdToken); if (profile == null) { throw new ApiException(HttpMessages.GoogleCodeIsInvalid, HttpStatusCode.Forbidden); } // Find accounts by searching for email address. var users = _unitOfWork.Accounts.Search(); users = users.Where(x => x.Email.Equals(profile.Email)); // Get the first matched account. var user = await users.FirstOrDefaultAsync(cancellationToken); // Account is available in the system. Check its status. if (user != null) { // Prevent account from logging into system because it is pending. if (user.Status == UserStatus.Pending) { throw new ApiException(HttpMessages.AccountIsPending, HttpStatusCode.Forbidden); } // Prevent account from logging into system because it is deleted. if (user.Status == UserStatus.Disabled) { throw new ApiException(HttpMessages.AccountIsDisabled, HttpStatusCode.Forbidden); } } else { // Initialize account instance. user = new User(); #if USE_IN_MEMORY user.Id = _unitOfWork.Accounts.Search().OrderByDescending(x => x.Id).Select(x => x.Id) .FirstOrDefault() + 1; #endif user.Email = profile.Email; user.Nickname = profile.Name; user.Role = UserRole.User; user.Photo = profile.Picture; user.JoinedTime = _baseTimeService.DateTimeUtcToUnix(DateTime.UtcNow); user.Type = UserKind.Google; user.Status = UserStatus.Available; // Add account to database. _unitOfWork.Accounts.Insert(user); await _unitOfWork.CommitAsync(cancellationToken); } return(user); }