public async Task <ServiceProviderResponse> CreateOrUpdateUserInfoRecordAsync( [FromHeader(Constant.OperationTrackingIdHeader)] string requestId, [FromHeader] string account, [FromBody] UserInfoRecordDescription description) { Validator.ArgumentNotNullOrEmpty(account, nameof(account)); Validator.ArgumentNotNull(description, nameof(description)); description.Validate(); var channel = SocialChannelHelper.Format(description.Channel); object channelId = null; object platform = null; object accessToken = null; description.Properties.TryGetValue(ChannelIdKey, out channelId); Validator.ArgumentNotNull(channelId, nameof(channelId)); description.Properties.TryGetValue(AccessTokenKey, out accessToken); Validator.ArgumentNotNull(accessToken, nameof(accessToken)); description.Properties.TryGetValue(PlatformKey, out platform); Validator.ArgumentNotNull(platform, nameof(platform)); var socialPlatform = SocialPlatformHelper.Format(platform.ToString()); var record = await this.engine.CreateOrUpdateUserInfoRecordAsync(account, channel, accessToken.ToString(), channelId.ToString(), socialPlatform, requestId, CancellationToken.None); return(new ServiceProviderResponse { StatusCode = HttpStatusCode.OK, JsonContent = record }); }
public async Task <UserInfoResult> CreateorUpdateUserInfoAsync(string account, string channelId, UserInfoRecordDescription description) { using (var ctx = new UserInfoEntities(this.connectionString)) { UserInfoResult userInfoResult = new UserInfoResult(); byte[] serializedProfileDescription; using (MemoryStream stream = new MemoryStream()) { BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(stream, description); serializedProfileDescription = stream.ToArray(); } var profile = await ctx.UserInfos.SingleOrDefaultAsync(f => f.Account == account && f.ChannelId == channelId && f.ChannelName == description.Channel); var startTime = DateTime.UtcNow; if (profile == null) { profile = new UserInfo { Account = account, ChannelName = description.Channel, ChannelId = channelId, ChannelProperties = serializedProfileDescription, CreatedTime = startTime, ModifiedTime = startTime }; ctx.UserInfos.Add(profile); userInfoResult.Action = ActionType.Create; } else { profile.ChannelProperties = serializedProfileDescription; profile.ModifiedTime = startTime; userInfoResult.Action = ActionType.Update; } await ctx.SaveChangesAsync(); userInfoResult.UserInfo = profile; return(userInfoResult); } }
public async Task <UserInfoRecord> CreateOrUpdateUserInfoRecordAsync(string account, string channel, string accessToken, string channelId, string socialPlatform, string requestId, CancellationToken cancellationToken) { UserInfoRecordDescription profileDescription = new UserInfoRecordDescription(channel); UserInfoRecordDescription description = new UserInfoRecordDescription(channel); description.Properties.Add(ChannelIdKey, channelId); description.Properties.Add(AccessTokenKey, accessToken); description.Properties.Add(PlatformKey, socialPlatform); PropertyCollection <object> profile = new PropertyCollection <object>(); var subscriptionId = await RequestHelper.GetSubscriptionId(account); UserInfo userInfo = new UserInfo(); bool updatedQuotaTotal = false; bool updatedQuotaMAU = false; try { // get appid for QQ and add into description if (channel == SocialChannelHelper.QQ) { var appId = await this.GetCredentialAsync(account, channel, socialPlatform); Validator.IsTrue <ArgumentException>(appId != null, nameof(appId), "No app_id for getting user information from {0}", description.Channel); description.Properties.Add(AppIdKey, appId); } // GET Profile from Social service with connector var connector = this.CreateConnector(channel); profile.Add(ChannelIdKey, channelId); var socialprofile = await connector.GetSocialProfileAsync(description.Properties); profile.Add(SocialProfileKey, socialprofile); profileDescription.Properties = profile; var storeAgent = await storeManager.GetStoreAgent(); userInfo = await storeAgent.UserInfoStore.GetUserInfoAsync(account, profileDescription.Channel, channelId.ToString()); // Create or update profile in Social store var userInfoResult = await storeAgent.UserInfoStore.CreateorUpdateUserInfoAsync(account, channelId.ToString(), profileDescription); // Update history in Social storage await this.telemetryManager.CreateSocialLoginHistoryRecordAsync(storeAgent, account, channel, channelId, socialPlatform, userInfoResult.Action.ToString(), userInfoResult.UserInfo.ModifiedTime); // Update Social Login MAU and Total quota for New user if (userInfo == null) { await QuotaCheckClient.AcquireQuotaAsync(account, Constants.SocialLoginTotal, 1); updatedQuotaTotal = true; await QuotaCheckClient.AcquireQuotaAsync(account, Constants.SocialLoginMAU, 1); updatedQuotaMAU = true; } else { // Update Social Login MAU quota for login first time this month if (userInfo.ModifiedTime < new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, 1)) { await QuotaCheckClient.AcquireQuotaAsync(account, Constants.SocialLoginMAU, 1); updatedQuotaMAU = true; } } var userInfoRecord = userInfoResult.UserInfo.ToUserInfoRecord(); this.metricManager.LogSocialLoginSuccess(1, account, subscriptionId ?? string.Empty, channel, socialPlatform); SocialProviderEventSource.Current.Info(requestId, this, nameof(this.CreateOrUpdateUserInfoRecordAsync), OperationStates.Succeeded, $"account: {account}, channel: {channel}, platform: {socialPlatform}, channelId: {channelId}"); return(userInfoRecord); } catch (Exception ex) { if (updatedQuotaTotal == true) { await QuotaCheckClient.ReleaseQuotaAsync(account, Constants.SocialLoginTotal, 1); } if (updatedQuotaMAU == true) { await QuotaCheckClient.ReleaseQuotaAsync(account, Constants.SocialLoginMAU, 1); } this.metricManager.LogSocialLoginFailed(1, account, subscriptionId ?? string.Empty, channel, socialPlatform); SocialProviderEventSource.Current.ErrorException(requestId, this, nameof(this.CreateOrUpdateUserInfoRecordAsync), OperationStates.Failed, $"Failed to create or update user information for account: {account}, channel: {channel}, platform: {socialPlatform}, channelId: {channelId}", ex); if ((ex is ArgumentException) || (ex is SocialChannelExceptionBase) || (ex is QuotaExceededException)) { throw; } throw new Exception(string.Format($"Failed to create or update user information for account: {account}, channel: {channel}, platform: {socialPlatform}, channelId: {channelId}")); } }