예제 #1
0
        private async Task GrantSteamCnPassword(OAuthGrantCustomExtensionContext context)
        {
            var  userName = context.Parameters["user_name"];
            var  uid      = context.Parameters["uid"];
            var  password = context.Parameters["password"];
            bool isUid;

            if (!string.IsNullOrWhiteSpace(userName))
            {
                // 用户名登录
                isUid = false;
            }
            else if (!string.IsNullOrWhiteSpace(uid))
            {
                // UID 登录
                userName = uid;
                isUid    = true;
            }
            else
            {
                context.SetError(Errors.InvalidIdField);
                return;
            }
            var steamCnUser = await SteamCnProvider.UserLoginAsync(userName, password, isUid);

            if (steamCnUser == null || steamCnUser.Uid < -1)
            {
                context.SetError(Errors.InvalidPassword);
                return;
            }
            if (steamCnUser.Uid == -1)
            {
                context.SetError(Errors.UserNonExistent);
                return;
            }
            var userManager = Global.Container.GetInstance <KeylolUserManager>();
            var user        =
                await userManager.FindAsync(new UserLoginInfo(KeylolLoginProviders.SteamCn, steamCnUser.Uid.ToString()));

            if (user == null)
            {
                context.SetError(Errors.NoCorrespondingUser, $"{steamCnUser.Email}:{steamCnUser.UserName}");
                return;
            }
            context.Validated(await userManager.CreateIdentityAsync(user, OAuthDefaults.AuthenticationType));
        }
예제 #2
0
        public async Task <IHttpActionResult> CreateOneBySms([NotNull] UserCreateOneBySmsRequestDto bySmsRequestDto)
        {
            // 检查手机是否合法
            if (string.IsNullOrWhiteSpace(bySmsRequestDto.PhoneNumber) || !Regex.IsMatch(bySmsRequestDto.PhoneNumber, Constants.ChinesePhoneNumberConstraint))
            {
                return(this.BadRequest(nameof(bySmsRequestDto.PhoneNumber), Errors.InvalidPhoneNumber));
            }

            // 检查手机是否已经注册
            if (bySmsRequestDto.PhoneNumber != null &&
                await _userManager.FindByPhoneNumberAsync(bySmsRequestDto.PhoneNumber) != null)
            {
                return(this.BadRequest(nameof(bySmsRequestDto.PhoneNumber), Errors.PhoneNumberUsed));
            }

            if (bySmsRequestDto.Email != null && (!new EmailAddressAttribute().IsValid(bySmsRequestDto.Email) ||
                                                  await _userManager.FindByEmailAsync(bySmsRequestDto.Email) != null))
            {
                bySmsRequestDto.Email = null;
            }

            var user = new KeylolUser
            {
                IdCode           = bySmsRequestDto.IdCode,
                UserName         = bySmsRequestDto.UserName,
                Email            = bySmsRequestDto.Email,
                PhoneNumber      = bySmsRequestDto.PhoneNumber,
                RegisterIp       = _owinContext.Request.RemoteIpAddress,
                SteamBindingTime = DateTime.Now
            };

            if (bySmsRequestDto.AvatarImage != null)
            {
                user.AvatarImage = bySmsRequestDto.AvatarImage;
            }

            if (bySmsRequestDto.SteamProfileName != null)
            {
                user.SteamProfileName = bySmsRequestDto.SteamProfileName;
            }

            var result = await _userManager.CreateAsync(user, bySmsRequestDto.Password);

            if (!result.Succeeded)
            {
                var    error = result.Errors.First();
                string propertyName;
                switch (error)
                {
                case Errors.InvalidIdCode:
                case Errors.IdCodeReserved:
                case Errors.IdCodeUsed:
                    propertyName = nameof(bySmsRequestDto.IdCode);
                    break;

                case Errors.UserNameInvalidCharacter:
                case Errors.UserNameInvalidLength:
                case Errors.UserNameUsed:
                    propertyName = nameof(bySmsRequestDto.UserName);
                    break;

                case Errors.InvalidEmail:
                    propertyName = nameof(bySmsRequestDto.Email);
                    break;

                case Errors.AvatarImageUntrusted:
                    propertyName = nameof(bySmsRequestDto.AvatarImage);
                    break;

                case Errors.PasswordAllWhitespace:
                case Errors.PasswordTooShort:
                    propertyName = nameof(bySmsRequestDto.Password);
                    break;

                default:
                    return(this.BadRequest(nameof(bySmsRequestDto), error));
                }
                return(this.BadRequest(nameof(bySmsRequestDto), propertyName, error));
            }

            // 检查 SMS Code
            if (bySmsRequestDto.SmsCode == null || bySmsRequestDto.PhoneNumber !=
                await _oneTimeToken.Consume <string>(bySmsRequestDto.SmsCode, OneTimeTokenPurpose.UserRegister))
            {
                return(this.BadRequest(nameof(bySmsRequestDto.SmsCode), Errors.InvalidToken));
            }

            await _userManager.AddLoginAsync(user.Id,
                                             new UserLoginInfo(KeylolLoginProviders.Sms, user.PhoneNumber));

            await _dbContext.SaveChangesAsync();

            if (bySmsRequestDto.SteamCnUserName != null)
            {
                var steamCnUser =
                    await SteamCnProvider.UserLoginAsync(bySmsRequestDto.SteamCnUserName, bySmsRequestDto.SteamCnPassword, false);

                if (steamCnUser != null && steamCnUser.Uid > 0 &&
                    await _userManager.FindAsync(new UserLoginInfo(KeylolLoginProviders.SteamCn,
                                                                   steamCnUser.Uid.ToString())) == null)
                {
                    await _userManager.AddLoginAsync(user.Id, new UserLoginInfo(KeylolLoginProviders.SteamCn,
                                                                                steamCnUser.Uid.ToString()));

                    user.SteamCnUserName    = steamCnUser.UserName;
                    user.SteamCnBindingTime = DateTime.Now;
                    await _dbContext.SaveChangesAsync();
                }
            }

            await _coupon.UpdateAsync(user, CouponEvent.新注册);

            var inviterText = string.Empty;

            if (bySmsRequestDto.InviterIdCode != null)
            {
                var inviter = await _userManager.FindByIdCodeAsync(bySmsRequestDto.InviterIdCode);

                if (inviter != null)
                {
                    user.InviterId = inviter.Id;
                    await _dbContext.SaveChangesAsync();

                    await _coupon.UpdateAsync(inviter, CouponEvent.邀请注册, new { UserId = user.Id });

                    await _coupon.UpdateAsync(user, CouponEvent.应邀注册, new { InviterId = user.Id });

                    inviterText = $"邀请人:{inviter.UserName} ({inviter.IdCode})\n";
                }
            }

            AutoSubscribe(user.Id);

            var operatorRoleId = (await _roleManager.FindByNameAsync(KeylolRoles.Operator)).Id;

            foreach (var @operator in await _dbContext.Users
                     .Where(u => u.Roles.Any(r => r.RoleId == operatorRoleId)).ToListAsync())
            {
                await _userManager.SendSteamChatMessageAsync(@operator,
                                                             $"[新用户注册 {user.RegisterTime}]\n#{user.Sid} {user.UserName}\nSteam 昵称:{user.SteamProfileName}\nIP:{user.RegisterIp}\n{inviterText}https://www.keylol.com/user/{user.IdCode}");
            }

            return(Ok(await _oneTimeToken.Generate(user.Id, TimeSpan.FromMinutes(1), OneTimeTokenPurpose.UserLogin)));
        }
예제 #3
0
        public async Task <IHttpActionResult> CreateOne([NotNull] ArticleCreateOrUpdateOneRequestDto requestDto)
        {
            var userId = User.Identity.GetUserId();

            if (!await _coupon.CanTriggerEventAsync(userId, CouponEvent.发布文章))
            {
                return(Unauthorized());
            }

            var article = new Models.Article
            {
                AuthorId   = userId,
                Title      = requestDto.Title,
                Content    = SanitizeRichText(requestDto.Content),
                CoverImage = SanitizeCoverImage(requestDto.CoverImage)
            };

            article.UnstyledContent = PlainTextFormatter.FlattenHtml(article.Content, true);

            if (!string.IsNullOrWhiteSpace(requestDto.Subtitle))
            {
                article.Subtitle = requestDto.Subtitle;
            }

            var targetPoint =
                await _dbContext.Points.Where(p => p.Id == requestDto.TargetPointId).SingleOrDefaultAsync();

            if (targetPoint == null)
            {
                return(this.BadRequest(nameof(requestDto), nameof(requestDto.TargetPointId), Errors.NonExistent));
            }

            targetPoint.LastActivityTime = DateTime.Now;
            article.TargetPointId        = targetPoint.Id;
            requestDto.AttachedPointIds  = requestDto.AttachedPointIds.Select(id => id.Trim())
                                           .Where(id => id != targetPoint.Id).Distinct().ToList();
            article.AttachedPoints = JsonConvert.SerializeObject(requestDto.AttachedPointIds);

            if (targetPoint.Type == PointType.Game || targetPoint.Type == PointType.Hardware)
            {
                article.Rating = requestDto.Rating;
                article.Pros   = JsonConvert.SerializeObject(requestDto.Pros ?? new List <string>());
                article.Cons   = JsonConvert.SerializeObject(requestDto.Cons ?? new List <string>());
            }

            if (requestDto.ReproductionRequirement != null)
            {
                article.ReproductionRequirement = JsonConvert.SerializeObject(requestDto.ReproductionRequirement);
            }

            _dbContext.Articles.Add(article);
            article.SidForAuthor = await _dbContext.Articles.Where(a => a.AuthorId == article.AuthorId)
                                   .Select(a => a.SidForAuthor)
                                   .DefaultIfEmpty(0)
                                   .MaxAsync() + 1;

            await _dbContext.SaveChangesAsync();

            await _coupon.UpdateAsync(await _userManager.FindByIdAsync(userId), CouponEvent.发布文章,
                                      new { ArticleId = article.Id });

            _mqChannel.SendMessage(string.Empty, MqClientProvider.PushHubRequestQueue, new PushHubRequestDto
            {
                Type      = ContentPushType.Article,
                ContentId = article.Id
            });
            _mqChannel.SendMessage(string.Empty, MqClientProvider.ImageGarageRequestQueue, new ImageGarageRequestDto
            {
                ContentType = ImageGarageRequestContentType.Article,
                ContentId   = article.Id
            });
            SteamCnProvider.TriggerArticleUpdate();
            return(Ok(article.SidForAuthor));
        }
예제 #4
0
        public async Task <IHttpActionResult> UpdateOne(string id, [NotNull] UserUpdateOneRequestDto requestDto)
        {
            var user = await _userManager.FindByIdAsync(id);

            if (user == null)
            {
                return(NotFound());
            }

            var currentUserId = User.Identity.GetUserId();

            if (currentUserId != user.Id && !User.IsInRole(KeylolRoles.Operator))
            {
                return(Unauthorized());
            }

            if (requestDto.Email != null)
            {
                user.Email = requestDto.Email;
            }

            if (requestDto.GamerTag != null)
            {
                user.GamerTag = requestDto.GamerTag;
            }

            if (requestDto.HeaderImage != null)
            {
                user.HeaderImage = requestDto.HeaderImage;
            }

            if (requestDto.AvatarImage != null)
            {
                user.AvatarImage = requestDto.AvatarImage;
            }

            if (requestDto.ThemeColor != null)
            {
                user.ThemeColor = requestDto.ThemeColor;
            }

            if (requestDto.LightThemeColor != null)
            {
                user.LightThemeColor = requestDto.LightThemeColor;
            }

            if (requestDto.NewPassword != null)
            {
                if (currentUserId == user.Id &&
                    (requestDto.Password == null || !await _userManager.CheckPasswordAsync(user, requestDto.Password)))
                {
                    return(this.BadRequest(nameof(requestDto), nameof(requestDto.Password), Errors.Invalid));
                }

                var passwordResult = await _userManager.ChangePasswordAsync(user, requestDto.NewPassword, false);

                if (!passwordResult.Succeeded)
                {
                    var    passwordError = passwordResult.Errors.First();
                    string errorPropertyName;
                    switch (passwordError)
                    {
                    case Errors.PasswordAllWhitespace:
                    case Errors.PasswordTooShort:
                        errorPropertyName = nameof(requestDto.NewPassword);
                        break;

                    default:
                        errorPropertyName = nameof(requestDto.Password);
                        break;
                    }
                    return(this.BadRequest(nameof(requestDto), errorPropertyName, passwordError));
                }
            }

            if (requestDto.SteamCnUserName != null)
            {
                var currentSteamCnUid = await _userManager.GetSteamCnUidAsync(user.Id);

                if (currentSteamCnUid != null)
                {
                    return(this.BadRequest(nameof(requestDto), nameof(requestDto.SteamCnUserName), Errors.TooMany));
                }
                var steamCnUser =
                    await SteamCnProvider.UserLoginAsync(requestDto.SteamCnUserName, requestDto.SteamCnPassword, false);

                if (steamCnUser == null || steamCnUser.Uid < -1)
                {
                    return(this.BadRequest(nameof(requestDto), nameof(requestDto.SteamCnPassword), Errors.Invalid));
                }
                if (steamCnUser.Uid == -1)
                {
                    return(this.BadRequest(nameof(requestDto), nameof(requestDto.SteamCnUserName), Errors.NonExistent));
                }
                if (await _userManager.FindAsync(new UserLoginInfo(KeylolLoginProviders.SteamCn,
                                                                   steamCnUser.Uid.ToString())) != null)
                {
                    return(this.BadRequest(nameof(requestDto), nameof(requestDto.SteamCnUserName), Errors.Duplicate));
                }
                foreach (var loginInfo in (await _userManager.GetLoginsAsync(user.Id))
                         .Where(l => l.LoginProvider == KeylolLoginProviders.SteamCn))
                {
                    await _userManager.RemoveLoginAsync(user.Id, loginInfo);
                }
                await _userManager.AddLoginAsync(user.Id, new UserLoginInfo(KeylolLoginProviders.SteamCn,
                                                                            steamCnUser.Uid.ToString()));

                user.SteamCnUserName    = steamCnUser.UserName;
                user.SteamCnBindingTime = DateTime.Now;
            }

            if (requestDto.LockoutEnabled != null)
            {
                user.LockoutEnabled = requestDto.LockoutEnabled.Value;
            }

            if (requestDto.OpenInNewWindow != null)
            {
                user.OpenInNewWindow = requestDto.OpenInNewWindow.Value;
            }

            if (requestDto.UseEnglishPointName != null)
            {
                user.PreferredPointName = requestDto.UseEnglishPointName.Value
                    ? PreferredPointName.English
                    : PreferredPointName.Chinese;
            }

            if (requestDto.NotifyOnArticleReplied != null)
            {
                user.NotifyOnArticleReplied = requestDto.NotifyOnArticleReplied.Value;
            }

            if (requestDto.NotifyOnCommentReplied != null)
            {
                user.NotifyOnCommentReplied = requestDto.NotifyOnCommentReplied.Value;
            }

            if (requestDto.NotifyOnActivityReplied != null)
            {
                user.NotifyOnActivityReplied = requestDto.NotifyOnActivityReplied.Value;
            }

            if (requestDto.NotifyOnArticleLiked != null)
            {
                user.NotifyOnArticleLiked = requestDto.NotifyOnArticleLiked.Value;
            }

            if (requestDto.NotifyOnCommentLiked != null)
            {
                user.NotifyOnCommentLiked = requestDto.NotifyOnCommentLiked.Value;
            }

            if (requestDto.NotifyOnActivityLiked != null)
            {
                user.NotifyOnActivityLiked = requestDto.NotifyOnActivityLiked.Value;
            }

            if (requestDto.NotifyOnSubscribed != null)
            {
                user.NotifyOnSubscribed = requestDto.NotifyOnSubscribed.Value;
            }

            if (requestDto.SteamNotifyOnArticleReplied != null)
            {
                user.SteamNotifyOnArticleReplied = requestDto.SteamNotifyOnArticleReplied.Value;
            }

            if (requestDto.SteamNotifyOnCommentReplied != null)
            {
                user.SteamNotifyOnCommentReplied = requestDto.SteamNotifyOnCommentReplied.Value;
            }

            if (requestDto.SteamNotifyOnActivityReplied != null)
            {
                user.SteamNotifyOnActivityReplied = requestDto.SteamNotifyOnActivityReplied.Value;
            }

            if (requestDto.SteamNotifyOnArticleLiked != null)
            {
                user.SteamNotifyOnArticleLiked = requestDto.SteamNotifyOnArticleLiked.Value;
            }

            if (requestDto.SteamNotifyOnCommentLiked != null)
            {
                user.SteamNotifyOnCommentLiked = requestDto.SteamNotifyOnCommentLiked.Value;
            }

            if (requestDto.SteamNotifyOnActivityLiked != null)
            {
                user.SteamNotifyOnActivityLiked = requestDto.SteamNotifyOnActivityLiked.Value;
            }

            if (requestDto.SteamNotifyOnSubscribed != null)
            {
                user.SteamNotifyOnSubscribed = requestDto.SteamNotifyOnSubscribed.Value;
            }

            if (requestDto.SteamNotifyOnSpotlighted != null)
            {
                user.SteamNotifyOnSpotlighted = requestDto.SteamNotifyOnSpotlighted.Value;
            }

            if (requestDto.SteamNotifyOnMissive != null)
            {
                user.SteamNotifyOnMissive = requestDto.SteamNotifyOnMissive.Value;
            }

            var updateResult = await _userManager.UpdateAsync(user);

            if (updateResult.Succeeded)
            {
                return(Ok());
            }

            var    updateError = updateResult.Errors.First();
            string propertyName;

            switch (updateError)
            {
            case Errors.UserNameInvalidCharacter:
            case Errors.UserNameInvalidLength:
            case Errors.UserNameUsed:
                propertyName = nameof(requestDto.UserName);
                break;

            case Errors.InvalidEmail:
            case Errors.EmailUsed:
                propertyName = nameof(requestDto.Email);
                break;

            case Errors.GamerTagInvalidLength:
                propertyName = nameof(requestDto.GamerTag);
                break;

            case Errors.AvatarImageUntrusted:
                propertyName = nameof(requestDto.AvatarImage);
                break;

            case Errors.HeaderImageUntrusted:
                propertyName = nameof(requestDto.HeaderImage);
                break;

            case Errors.InvalidThemeColor:
                propertyName = nameof(requestDto.ThemeColor);
                break;

            case Errors.InvalidLightThemeColor:
                propertyName = nameof(requestDto.LightThemeColor);
                break;

            default:
                return(this.BadRequest(nameof(requestDto), updateError));
            }
            return(this.BadRequest(nameof(requestDto), propertyName, updateError));
        }