/// <summary>
        /// Occurs after the action method is invoked.
        /// </summary>
        /// <param name="context">Indicating the executed context.</param>
        public override void OnActionExecuted(HttpActionExecutedContext context)
        {
            if (context.Exception != null)
            {
                CustomTrace.TraceError(
                    context.Exception,
                    "Execute request exception: url:{0}, arguments: {1}",
                    context.Request.RequestUri,
                    context.ActionContext.ActionArguments);

                var errorCode = UCenterErrorCode.InternalHttpServerError;

                if (context.Exception is UCenterException)
                {
                    errorCode = (context.Exception as UCenterException).ErrorCode;
                }
                else if (context.Exception is MongoException)
                {
                    errorCode = UCenterErrorCode.InternalDatabaseError;
                }

                string errorMessage = context.Exception.Message;
                context.Response = this.CreateErrorResponseMessage(errorCode, errorMessage);
            }

            base.OnActionExecuted(context);
        }
示例#2
0
        private static string VerifySignedHash(
            string str_DataToVerify,
            string str_SignedData,
            string str_publicKeyFilePath)
        {
            byte[] signedData = Convert.FromBase64String(str_SignedData);

            var byteConverter = new UTF8Encoding();

            byte[] dataToVerify = byteConverter.GetBytes(str_DataToVerify);
            try
            {
                string publicKeyPEM = File.ReadAllText(str_publicKeyFilePath);
                var    rsa          = new RSACryptoServiceProvider();

                rsa.PersistKeyInCsp = false;
                rsa.LoadPublicKeyPEM(publicKeyPEM);

                if (rsa.VerifyData(dataToVerify, "SHA256", signedData))
                {
                    return("verify success");
                }

                return("verify fail");
            }
            catch (CryptographicException e)
            {
                CustomTrace.TraceError(e);
                return("verify error");
            }
        }
        private void LogInboundRequest(HttpActionContext context)
        {
            try
            {
                string clientIpAddress = IPHelper.GetClientIpAddress(context.Request);
                string request         = context.Request.ToString();
                string arguments       = context
                                         .ActionArguments.Select(a => $"{a.Value.DumpToString(a.Key)}")
                                         .JoinToString(",");

                string message = $"Inbound Request IP: {clientIpAddress}\n\tRequest: {request}\n\n\t Arguments: {arguments}";
                CustomTrace.TraceInformation(message);
            }
            catch (Exception ex)
            {
                CustomTrace.TraceError(ex, $"Log Inbound Request Error: \n\t{context.Request}");
            }
        }
        public async Task <string> UploadBlobAsync(string blobName, Stream stream, CancellationToken token)
        {
            try
            {
                string key = $"{this.settings.ImageContainerName}/{blobName}";
                this.CreateBucketIfNotExists();
                var result = await Task <PutObjectResult> .Factory.FromAsync(
                    this.client.BeginPutObject,
                    this.client.EndPutObject,
                    this.bucketName,
                    key,
                    stream,
                    null);

                var uri = this.client.GeneratePresignedUri(this.bucketName, key);

                return(uri.GetLeftPart(UriPartial.Path));
            }
            catch (Exception ex)
            {
                CustomTrace.TraceError(ex, "Error while upload file to ali oss");
                throw;
            }
        }
示例#5
0
        public WebContext(ExportProvider exportProvider, Settings settings)
        {
            this.settings    = settings;
            this.BaseAddress = $"http://{this.settings.ServerHost}:{this.settings.ServerPort}";

            if (UseSelfHost())
            {
                try
                {
                    this.configuration = new HttpSelfHostConfiguration(this.BaseAddress);
                    this.configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
                    this.configuration.MapHttpAttributeRoutes();
                    WebApplicationManager.InitializeApplication(configuration, exportProvider);

                    this.server = new HttpSelfHostServer(configuration);
                    this.server.OpenAsync().Wait();
                }
                catch (Exception ex)
                {
                    CustomTrace.TraceError(ex);
                    throw;
                }
            }
        }
示例#6
0
        public async Task <IActionResult> Register([FromBody] AccountRegisterRequestInfo info, CancellationToken token)
        {
            // 检测注册信息合法性
            ValidateAccount(info);

            try
            {
                // 检测帐号名是否可以被注册
                var oldAccountEntity = await this.Database.Accounts.GetSingleAsync(
                    a => a.AccountName == info.AccountName,
                    //|| a.Email == info.Email
                    //|| a.Phone == info.Phone,
                    token);

                if (oldAccountEntity != null)
                {
                    throw new UCenterException(UCenterErrorCode.AccountNameAlreadyExist);
                }

                // 检查Device是否绑定了游客号
                AccountEntity accountEntity = null;
                if (info != null &&
                    !string.IsNullOrEmpty(info.AppId) &&
                    info.Device != null &&
                    !string.IsNullOrEmpty(info.Device.Id))
                {
                    string guestDeviceId     = $"{info.AppId}_{info.Device.Id}";
                    var    guestDeviceEntity = await this.Database.GuestDevices.GetSingleAsync(guestDeviceId, token);

                    if (guestDeviceEntity != null)
                    {
                        accountEntity = await this.Database.Accounts.GetSingleAsync(guestDeviceEntity.AccountId, token);
                    }
                }

                bool guestConvert = true;
                if (accountEntity == null)
                {
                    guestConvert = false;

                    // 没有绑定游客号,正常注册
                    accountEntity = new AccountEntity
                    {
                        Id = Guid.NewGuid().ToString(),
                    };
                }

                accountEntity.AccountName   = info.AccountName;
                accountEntity.AccountType   = AccountType.NormalAccount;
                accountEntity.AccountStatus = AccountStatus.Active;
                accountEntity.Name          = info.Name;
                accountEntity.Identity      = info.Identity;
                accountEntity.Password      = EncryptHelper.ComputeHash(info.Password);
                accountEntity.SuperPassword = EncryptHelper.ComputeHash(info.SuperPassword);
                accountEntity.Phone         = info.Phone;
                accountEntity.Email         = info.Email;
                accountEntity.Gender        = info.Gender;

                //var placeholders = new[]
                //    {
                //        this.GenerateKeyPlaceholder(accountEntity.AccountName, KeyType.Name, accountEntity.Id, accountEntity.AccountName),
                //        this.GenerateKeyPlaceholder(accountEntity.Phone, KeyType.Phone, accountEntity.Id, accountEntity.AccountName),
                //        this.GenerateKeyPlaceholder(accountEntity.Email, KeyType.Email, accountEntity.Id, accountEntity.AccountName)
                //    };

                //foreach (var placeholder in placeholders)
                //{
                //    if (!string.IsNullOrEmpty(placeholder.Name))
                //    {
                //        await this.Database.KeyPlaceholders.InsertAsync(placeholder, token);
                //        removeTempsIfError.Add(placeholder);
                //    }
                //}

                if (guestConvert)
                {
                    // 绑定了游客号,游客号转正
                    await this.Database.Accounts.UpsertAsync(accountEntity, token);

                    try
                    {
                        await this.Database.GuestDevices.DeleteAsync(
                            d => d.AppId == info.AppId && d.AccountId == accountEntity.Id,
                            token);
                    }
                    catch (Exception ex)
                    {
                        CustomTrace.TraceError(ex, "Error to remove guest device");
                    }

                    await this.TraceAccountEvent(accountEntity, "GuestConvert", token : token);
                }
                else
                {
                    // 没有绑定游客号,正常注册

                    // Remove this from UCenter for performance concern
                    // If user does not have default profile icon, app client should use local default one
                    // accountEntity.ProfileImage = await this.storageContext.CopyBlobAsync(
                    //    accountEntity.Gender == Gender.Female ? this.settings.DefaultProfileImageForFemaleBlobName : this.settings.DefaultProfileImageForMaleBlobName,
                    //    this.settings.ProfileImageForBlobNameTemplate.FormatInvariant(accountEntity.Id),
                    //    token);

                    // accountEntity.ProfileThumbnail = await this.storageContext.CopyBlobAsync(
                    //    accountEntity.Gender == Gender.Female
                    //        ? this.settings.DefaultProfileThumbnailForFemaleBlobName
                    //        : this.settings.DefaultProfileThumbnailForMaleBlobName,
                    //    this.settings.ProfileThumbnailForBlobNameTemplate.FormatInvariant(accountEntity.Id),
                    //    token);

                    await this.Database.Accounts.InsertAsync(accountEntity, token);

                    await TraceAccountEvent(accountEntity, "Register", info.Device, token : token);
                }

                if (info.Device != null)
                {
                    await LogDeviceInfo(info.Device, token);
                }

                return(this.CreateSuccessResult(this.ToResponse <AccountRegisterResponse>(accountEntity)));
            }
            catch (Exception ex)
            {
                CustomTrace.TraceError(ex, "Account.Register Exception:AccoundName={info.AccountName}");
                throw;
            }
        }
示例#7
0
        public async Task <IHttpActionResult> Register([FromBody] AccountRegisterRequestInfo info, CancellationToken token)
        {
            CustomTrace.TraceInformation($"Account.Register AccountName={info.AccountName}");

            if (!ValidateAccountName(info.AccountName))
            {
                // TODO: Change to AccountRegisterFailedInvalidName in next client refresh
                throw new UCenterException(UCenterErrorCode.AccountRegisterFailedAlreadyExist);
            }

            var removeTempsIfError = new List <KeyPlaceholderEntity>();
            var error = false;

            try
            {
                var account = await this.Database.Accounts.GetSingleAsync(a => a.AccountName == info.AccountName, token);

                if (account != null)
                {
                    throw new UCenterException(UCenterErrorCode.AccountRegisterFailedAlreadyExist);
                }

                account = new AccountEntity
                {
                    Id            = Guid.NewGuid().ToString(),
                    AccountName   = info.AccountName,
                    IsGuest       = false,
                    Name          = info.Name,
                    Email         = info.Email,
                    IdentityNum   = info.IdentityNum,
                    Password      = EncryptHashManager.ComputeHash(info.Password),
                    SuperPassword = EncryptHashManager.ComputeHash(info.SuperPassword),
                    PhoneNum      = info.PhoneNum,
                    Sex           = info.Sex
                };

                var placeholders = new[]
                {
                    this.GenerateKeyPlaceholder(account.AccountName, KeyType.Name, account.Id, account.AccountName),
                    this.GenerateKeyPlaceholder(account.PhoneNum, KeyType.Phone, account.Id, account.AccountName),
                    this.GenerateKeyPlaceholder(account.Email, KeyType.Email, account.Id, account.AccountName)
                };

                foreach (var placeholder in placeholders)
                {
                    if (!string.IsNullOrEmpty(placeholder.Name))
                    {
                        await this.Database.KeyPlaceholders.InsertAsync(placeholder, token);

                        removeTempsIfError.Add(placeholder);
                    }
                }

                // set the default profiles
                account.ProfileImage = await this.storageContext.CopyBlobAsync(
                    account.Sex == Sex.Female?this.settings.DefaultProfileImageForFemaleBlobName : this.settings.DefaultProfileImageForMaleBlobName,
                    this.settings.ProfileImageForBlobNameTemplate.FormatInvariant(account.Id),
                    token);

                account.ProfileThumbnail = await this.storageContext.CopyBlobAsync(
                    account.Sex == Sex.Female
                    ?this.settings.DefaultProfileThumbnailForFemaleBlobName
                    : this.settings.DefaultProfileThumbnailForMaleBlobName,
                    this.settings.ProfileThumbnailForBlobNameTemplate.FormatInvariant(account.Id),
                    token);

                await this.Database.Accounts.InsertAsync(account, token);

                return(this.CreateSuccessResult(this.ToResponse <AccountRegisterResponse>(account)));
            }
            catch (Exception ex)
            {
                CustomTrace.TraceError(ex, "Account.Register Exception:AccoundName={info.AccountName}");

                error = true;
                if (ex is MongoWriteException)
                {
                    var mex = ex as MongoWriteException;

                    if (mex.WriteError.Category == ServerErrorCategory.DuplicateKey)
                    {
                        throw new UCenterException(UCenterErrorCode.AccountRegisterFailedAlreadyExist, ex);
                    }
                }

                throw;
            }
            finally
            {
                if (error)
                {
                    try
                    {
                        foreach (var item in removeTempsIfError)
                        {
                            this.Database.KeyPlaceholders.DeleteAsync(item, token).Wait(token);
                        }
                    }
                    catch (Exception ex)
                    {
                        CustomTrace.TraceError(ex, "Error to remove placeholder");
                    }
                }
            }
        }
示例#8
0
        public async Task <IHttpActionResult> CreateCharge([FromBody] ChargeInfo info, CancellationToken token)
        {
            CustomTrace.TraceInformation($"AppServer.CreateCharge\nAppId={info.AppId}\nAccountId={info.AccountId}");

            try
            {
                var account = await this.Database.Accounts.GetSingleAsync(info.AccountId, token);

                var app = await this.Database.Apps.GetSingleAsync(info.AppId, token);

                var orderEntity = new OrderEntity
                {
                    Id          = Guid.NewGuid().ToString(),
                    AppId       = info.AppId,
                    AppName     = app == null ? null : app.Name,
                    AccountId   = info.AccountId,
                    AccountName = account == null ? null : account.AccountName,
                    State       = OrderState.Created,
                    CreatedTime = DateTime.UtcNow
                };

                await this.Database.Orders.InsertAsync(orderEntity, token);

                // TODO: Replace with live key
                Pingpp.SetApiKey("sk_test_zXnD8KKOyfn1vDuj9SG8ibfT");

                // TODO: Fix hard code path
                var certFile = this.GetCertFilePath("rsa_private_key.pem");
                Pingpp.SetPrivateKeyPath(certFile);

                var    appId          = "app_H4yDu5COi1O4SWvz";
                var    r              = new Random();
                string orderNoPostfix = r.Next(0, 1000000).ToString("D6");
                string orderNo        = $"{DateTime.Now.ToString("yyyyMMddHHmmssffff")}_{orderNoPostfix}";
                var    amount         = info.Amount;

                // var channel = "alipay";
                // var currency = "cny";
                // 交易请求参数,这里只列出必填参数,可选参数请参考 https://pingxx.com/document/api#api-c-new
                var chargeParams = new Dictionary <string, object>
                {
                    { "order_no", new Random().Next(1, 999999999) },
                    { "amount", amount },
                    { "channel", "wx" },
                    { "currency", "cny" },
                    { "subject", info.Subject },
                    { "body", info.Body },
                    { "client_ip", "127.0.0.1" },
                    { "app", new Dictionary <string, string> {
                          { "id", appId }
                      } }
                };

                var charge = Charge.Create(chargeParams);

                return(this.CreateSuccessResult(charge));
            }
            catch (Exception ex)
            {
                CustomTrace.TraceError(ex, "Failed to create charge");
                throw new UCenterException(UCenterErrorCode.PaymentCreateChargeFailed, ex.Message);
            }
        }