private async Task <IUserAuthenticationCode> CreateDirectLoginCodeAsync(ISessionIdentity identity, ICreateUserAuthenticationCodeRequest request) { if (identity.IdentityType != IdentityType.Bot) { throw new HttpStatusException($"NotBot:Identity{identity.IdentityType}") { Status = StatusCode.Unauthorized } } ; if (string.IsNullOrEmpty(request.TargetUser)) { throw new HttpStatusException("Empty:CreateUserAuthenticationCodeRequest.TargetUser") { Status = StatusCode.BadRequest } } ; var table = tableClient.GetTableReference(DirectLoginCodeTableName); var retry = true; while (retry) { retry = false; var now = DateTime.UtcNow; var prefix = now.ToString("yyyyMMdd"); var code = prefix + GenerateCode(32); var expireIn = now.AddMinutes(1).Ticks; var codeEntity = new DirectLoginCodeEntity { PartitionKey = prefix, RowKey = code, TargetUser = request.TargetUser, ExpireIn = expireIn, ReqVia = identity.Name, Status = (int)StatusCode.Pending }; var status = await table.InsertAsync(codeEntity); if (status == 409) { retry = true; continue; } if (status >= 400) { throw new HttpStatusException("EntityErrorInsert:DirectLoginCode", status); } return(new UserAuthenticationCode { Code = code, ExpireIn = expireIn, TargetUser = codeEntity.TargetUser }); } throw new NotImplementedException(); }
public async Task <IUserAuthenticationCode> CreateCodeAsync(ISessionIdentity identity, ICreateUserAuthenticationCodeRequest request) { if (identity == null || !identity.IsAuthenticated) { throw new HttpStatusException("Unauthorized:Identity") { Status = StatusCode.Unauthorized } } ; if (request.CodeType == UserAuthenticationCodeType.AcknowledgeCode) { return(await CreateAcknowledgeCodeAsync(identity, request)); } else if (request.CodeType == UserAuthenticationCodeType.DirectLoginCode) { return(await CreateDirectLoginCodeAsync(identity, request)); } else { throw new HttpStatusException($"Unknown:CreateUserAuthenticationCodeRequest.CodeType({request.CodeType})") { Status = StatusCode.BadRequest }; } }
private async Task <IUserAuthenticationCode> CreateAcknowledgeCodeAsync(ISessionIdentity identity, ICreateUserAuthenticationCodeRequest request) { if (identity.IdentityType != IdentityType.App) { throw new HttpStatusException($"NotApp:Identity({identity.IdentityType})") { Status = StatusCode.Unauthorized } } ; var table = tableClient.GetTableReference(AcknowledgeCodeTableName); var retry = true; while (retry) { retry = false; var code = GenerateCode(6); var now = DateTime.UtcNow; var nowTicks = now.Ticks; var expireIn = now.AddMinutes(1).Ticks; var availableAfter = now.AddMinutes(5).Ticks; var rowKey = nowTicks.ToString("X16"); var result = await table.RetrieveAsync <AcknowledgeCodeStatusEntity>(code, 0L.ToString("X16")); if (result.HttpStatusCode >= 400 && result.HttpStatusCode != 404) { throw new HttpStatusException("EntityErrorRetrieve:AcknowledgeCodeStatus", result.HttpStatusCode); } var statusEntity = result.Entity; if (statusEntity == null || statusEntity.AvailableAfter < nowTicks) { if (statusEntity == null) { statusEntity = new AcknowledgeCodeStatusEntity { PartitionKey = code, RowKey = 0L.ToString("X16"), }; } statusEntity.CurrentRowKey = rowKey; statusEntity.AvailableAfter = availableAfter; var status = await table.InsertOrMergeAsync(statusEntity); if (status >= 400) { throw new HttpStatusException("EntityErrorUpdate:AcknowledgeCodeStatus", status); } } else { // not available, just retry retry = true; continue; } var codeEntity = new AcknowledgeCodeEntity { PartitionKey = code, RowKey = rowKey, ExpireIn = expireIn, Status = (int)StatusCode.Pending, TargetUser = request.TargetUser, ReqDeviceId = identity.ClientDeviceId, ReqSessionId = identity.ClientSessionId }; var insertStatus = await table.InsertAsync(codeEntity); if (insertStatus >= 400) { throw new HttpStatusException("EntityErrorInsert:AcknowledgeCode", insertStatus); } return(new UserAuthenticationCode { Code = code, ExpireIn = expireIn, TargetUser = codeEntity.TargetUser }); } throw new NotImplementedException(); }