コード例 #1
0
        public async Task <IHttpActionResult> Login([FromBody] AccountLoginInfo info, CancellationToken token)
        {
            CustomTrace.TraceInformation($"Account.Login AccountName={info.AccountName}");

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

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

            if (!EncryptHashManager.VerifyHash(info.Password, account.Password))
            {
                await this.RecordLogin(
                    account,
                    UCenterErrorCode.AccountLoginFailedPasswordNotMatch,
                    "The account name and password do not match",
                    token);

                throw new UCenterException(UCenterErrorCode.AccountLoginFailedPasswordNotMatch);
            }

            account.LastLoginDateTime = DateTime.UtcNow;
            account.Token             = EncryptHashManager.GenerateToken();
            await this.Database.Accounts.UpsertAsync(account, token);

            await this.RecordLogin(account, UCenterErrorCode.Success, token : token);

            return(this.CreateSuccessResult(this.ToResponse <AccountLoginResponse>(account)));
        }
コード例 #2
0
        public async Task <IHttpActionResult> PingPlusPlusWebHook(CancellationToken token)
        {
            CustomTrace.TraceInformation("AppServer.PingPlusPlusWebHook");

            // 获取 post 的 event对象
            var inputData = Request.Content.ReadAsStringAsync().Result;

            CustomTrace.TraceInformation("Received event\n" + inputData);

            // 获取 header 中的签名
            IEnumerable <string> headerValues;
            string sig = string.Empty;

            if (Request.Headers.TryGetValues("x-pingplusplus-signature", out headerValues))
            {
                sig = headerValues.FirstOrDefault();
            }

            // 公钥路径(请检查你的公钥 .pem 文件存放路径)
            string certPath = this.GetCertFilePath("rsa_public_key.pem");

            // 验证签名
            VerifySignedHash(inputData, sig, certPath);

            await this.ProcessOrderAsync(inputData, token);

            return(this.Ok());
        }
コード例 #3
0
        public async Task <IHttpActionResult> ResetPassword([FromBody] AccountResetPasswordInfo info, CancellationToken token)
        {
            CustomTrace.TraceInformation($"Account.ResetPassword AccountName={info.AccountName}");

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

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

            if (!EncryptHashManager.VerifyHash(info.SuperPassword, account.SuperPassword))
            {
                await this.RecordLogin(
                    account,
                    UCenterErrorCode.AccountLoginFailedPasswordNotMatch,
                    "The super password provided is incorrect",
                    token);

                throw new UCenterException(UCenterErrorCode.AccountLoginFailedPasswordNotMatch);
            }

            account.Password = EncryptHashManager.ComputeHash(info.Password);
            await this.Database.Accounts.UpsertAsync(account, token);

            await this.RecordLogin(account, UCenterErrorCode.Success, "Reset password successfully.", token);

            return(this.CreateSuccessResult(this.ToResponse <AccountResetPasswordResponse>(account)));
        }
コード例 #4
0
        public async Task <IHttpActionResult> UploadProfileImage([FromUri] string accountId, CancellationToken token)
        {
            CustomTrace.TraceInformation($"Account.UploadProfileImage AccountId={accountId}");

            var account = await this.GetAndVerifyAccount(accountId, token);

            using (var stream = await this.Request.Content.ReadAsStreamAsync())
            {
                var image = Image.FromStream(stream);
                using (var thumbnailStream = this.GetThumbprintStream(image))
                {
                    var smallProfileName = this.settings.ProfileThumbnailForBlobNameTemplate.FormatInvariant(accountId);
                    account.ProfileThumbnail =
                        await this.storageContext.UploadBlobAsync(smallProfileName, thumbnailStream, token);
                }

                string profileName = this.settings.ProfileImageForBlobNameTemplate.FormatInvariant(accountId);
                stream.Seek(0, SeekOrigin.Begin);
                account.ProfileImage = await this.storageContext.UploadBlobAsync(profileName, stream, token);

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

                await this.RecordLogin(account, UCenterErrorCode.Success, "Profile image uploaded successfully.", token);

                return(this.CreateSuccessResult(
                           this.ToResponse <AccountUploadProfileImageResponse>(account)));
            }
        }
コード例 #5
0
        public async Task <IHttpActionResult> CreateApp([FromBody] AppInfo info, CancellationToken token)
        {
            CustomTrace.TraceInformation("[CreateApp] AppId={0}", info.AppId);

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

            if (app == null)
            {
                // todo: currently, app name equals app id.
                app = new AppEntity
                {
                    Id        = info.AppId,
                    Name      = info.AppId,
                    AppSecret = info.AppSecret,
                };

                await this.Database.Apps.InsertAsync(app, token);
            }

            var response = new AppResponse
            {
                AppId     = info.AppId,
                AppSecret = info.AppSecret
            };

            return(this.CreateSuccessResult(response));
        }
コード例 #6
0
        public async Task <IHttpActionResult> CreateAppConfiguration([FromBody] AppConfigurationInfo info, CancellationToken token)
        {
            CustomTrace.TraceInformation("[CreateAppConfiguration] AppId={0}", info.AppId);

            var appConfiguration = await this.Database.AppConfigurations.GetSingleAsync(info.AppId, token);

            if (appConfiguration == null)
            {
                appConfiguration = new AppConfigurationEntity
                {
                    Id            = info.AppId,
                    Configuration = info.Configuration,
                };

                await this.Database.AppConfigurations.InsertAsync(appConfiguration, token);
            }
            else
            {
                await this.Database.AppConfigurations.UpsertAsync(appConfiguration, token);
            }

            var response = new AppConfigurationResponse
            {
                AppId         = info.AppId,
                Configuration = info.Configuration
            };

            return(this.CreateSuccessResult(response));
        }
コード例 #7
0
        public async Task <IHttpActionResult> Convert([FromBody] AccountConvertInfo info, CancellationToken token)
        {
            CustomTrace.TraceInformation($"Account.Convert AccountName={info.AccountName}");

            var account = await this.GetAndVerifyAccount(info.AccountId, token);

            if (!EncryptHashManager.VerifyHash(info.OldPassword, account.Password))
            {
                await this.RecordLogin(
                    account,
                    UCenterErrorCode.AccountLoginFailedPasswordNotMatch,
                    "The account name and password do not match",
                    token);

                throw new UCenterException(UCenterErrorCode.AccountLoginFailedPasswordNotMatch);
            }

            account.AccountName   = info.AccountName;
            account.IsGuest       = false;
            account.Name          = info.Name;
            account.IdentityNum   = info.IdentityNum;
            account.Password      = EncryptHashManager.ComputeHash(info.Password);
            account.SuperPassword = EncryptHashManager.ComputeHash(info.SuperPassword);
            account.PhoneNum      = info.PhoneNum;
            account.Email         = info.Email;
            account.Sex           = info.Sex;
            await this.Database.Accounts.UpsertAsync(account, token);

            await this.RecordLogin(account, UCenterErrorCode.Success, "Account converted successfully.", token);

            return(this.CreateSuccessResult(this.ToResponse <AccountRegisterResponse>(account)));
        }
コード例 #8
0
        public async Task <IHttpActionResult> GuestLogin([FromBody] AccountLoginInfo info, CancellationToken token)
        {
            CustomTrace.TraceInformation("Account.GuestLogin");

            var    r = new Random();
            string accountNamePostfix = r.Next(0, 1000000).ToString("D6");
            string accountName        = $"uc_{DateTime.Now.ToString("yyyyMMddHHmmssffff")}_{accountNamePostfix}";
            string accountToken       = EncryptHashManager.GenerateToken();
            string password           = Guid.NewGuid().ToString();

            var account = new AccountEntity
            {
                Id          = Guid.NewGuid().ToString(),
                AccountName = accountName,
                IsGuest     = true,
                Password    = EncryptHashManager.ComputeHash(password),
                Token       = EncryptHashManager.GenerateToken()
            };

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

            var response = new AccountGuestLoginResponse
            {
                AccountId   = account.Id,
                AccountName = accountName,
                Token       = accountToken,
                Password    = password
            };

            return(this.CreateSuccessResult(response));
        }
コード例 #9
0
        public void TestEncryptAndCompare()
        {
            string password = Guid.NewGuid().ToString();
            var    hash     = EncryptHashManager.ComputeHash(password);

            CustomTrace.TraceInformation("Hash code is: {0}", hash);
            Assert.IsFalse(EncryptHashManager.VerifyHash(Guid.NewGuid().ToString(), hash));
            Assert.IsTrue(EncryptHashManager.VerifyHash(password, hash));
        }
コード例 #10
0
        public async Task <IHttpActionResult> GetClientIpArea(CancellationToken token)
        {
            CustomTrace.TraceInformation("AppClient.GetClientIpArea");

            string ipAddress = IPHelper.GetClientIpAddress(Request);
            var    response  = await IPHelper.GetIPInfoAsync(ipAddress, token);

            return(this.CreateSuccessResult(response));
        }
コード例 #11
0
        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}");
            }
        }
コード例 #12
0
        public async Task <IHttpActionResult> VerifyAccount(AppVerifyAccountInfo info, CancellationToken token)
        {
            CustomTrace.TraceInformation($"App.VerifyAccount AppId={info.AppId} AccountId={info.AccountId}");

            await this.VerifyApp(info.AppId, info.AppSecret, token);

            var account = await this.GetAndVerifyAccount(info.AccountId, info.AccountToken, token);

            var result = new AppVerifyAccountResponse();

            result.AccountId          = account.Id;
            result.AccountName        = account.AccountName;
            result.AccountToken       = account.Token;
            result.LastLoginDateTime  = account.LastLoginDateTime;
            result.LastVerifyDateTime = DateTime.UtcNow;

            return(this.CreateSuccessResult(result));
        }
コード例 #13
0
        public async Task <IHttpActionResult> ReadAppAccountData(AppAccountDataInfo info, CancellationToken token)
        {
            CustomTrace.TraceInformation($"App.ReadAppAccountData AppId={info.AppId} AccountId={info.AccountId}");

            await this.VerifyApp(info.AppId, info.AppSecret, token);

            var account = await this.GetAndVerifyAccount(info.AccountId, token);

            var dataId      = this.CreateAppAccountDataId(info.AppId, info.AccountId);
            var accountData = await this.Database.AppAccountDatas.GetSingleAsync(dataId, token);

            var response = new AppAccountDataResponse
            {
                AppId     = info.AppId,
                AccountId = info.AccountId,
                Data      = accountData?.Data
            };

            return(this.CreateSuccessResult(response));
        }
コード例 #14
0
        public async Task <IHttpActionResult> GetAppConfiguration([FromUri] string appId, CancellationToken token)
        {
            CustomTrace.TraceInformation($"AppClient.GetAppConfiguration AppId={appId}");

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

            if (app == null)
            {
                throw new UCenterException(UCenterErrorCode.AppNotExit);
            }

            var appConfiguration = await this.Database.AppConfigurations.GetSingleAsync(appId, token);

            var response = new AppConfigurationResponse
            {
                AppId         = app.Id,
                Configuration = appConfiguration == null ? string.Empty : appConfiguration.Configuration
            };

            return(this.CreateSuccessResult(response));
        }
コード例 #15
0
        public async Task <IHttpActionResult> WriteAppAccountData(AppAccountDataInfo info, CancellationToken token)
        {
            CustomTrace.TraceInformation($"App.WriteAppAccountData AppId={info.AppId} AccountId={info.AccountId}");

            await this.VerifyApp(info.AppId, info.AppSecret, token);

            var account = await this.GetAndVerifyAccount(info.AccountId, token);

            var dataId      = this.CreateAppAccountDataId(info.AppId, info.AccountId);
            var accountData = await this.Database.AppAccountDatas.GetSingleAsync(dataId, token);

            if (accountData != null)
            {
                accountData.Data = info.Data;
            }
            else
            {
                accountData = new AppAccountDataEntity
                {
                    Id        = dataId,
                    AppId     = info.AppId,
                    AccountId = info.AccountId,
                    Data      = info.Data
                };
            }

            await this.Database.AppAccountDatas.UpsertAsync(accountData, token);

            var response = new AppAccountDataResponse
            {
                AppId     = info.AppId,
                AccountId = info.AccountId,
                Data      = accountData.Data
            };

            return(this.CreateSuccessResult(response));
        }
コード例 #16
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");
                    }
                }
            }
        }
コード例 #17
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);
            }
        }