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))); }
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()); }
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))); }
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))); } }
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)); }
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)); }
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))); }
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)); }
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)); }
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)); }
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 <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)); }
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)); }
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)); }
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)); }
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"); } } } }
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); } }