private async Task <IUserAuthenticationToken> TryGetTokenByAcknowledgeCodeAsync(ISessionIdentity identity, IGetUserAuthenticationCodeRequest request)
        {
            var table = tableClient.GetTableReference(AcknowledgeCodeTableName);

            var statusResult = await table.RetrieveAsync <AcknowledgeCodeStatusEntity>(request.Code, 0L.ToString("X16"));

            if (statusResult.HttpStatusCode == 404)
            {
                throw new HttpStatusException("EntityNotFound:AcknowledgeCodeStatus", statusResult.HttpStatusCode)
                      {
                          Status = StatusCode.NotFound
                      }
            }
            ;
            if (statusResult.HttpStatusCode >= 400)
            {
                throw new HttpStatusException("EntityErrorRetrieve:AcknowledgeCodeStatus", statusResult.HttpStatusCode);
            }

            var statusEntity = statusResult.Entity;

            var now      = DateTime.UtcNow;
            var nowTicks = now.Ticks;

            if (statusEntity.AvailableAfter < nowTicks)
            {
                throw new HttpStatusException("Expired:AcknowledgeCodeStatus")
                      {
                          Status = StatusCode.NotFound
                      }
            }
            ;

            var codeResult = await table.RetrieveAsync <AcknowledgeCodeEntity>(request.Code, statusEntity.CurrentRowKey);

            if (codeResult.HttpStatusCode >= 400)
            {
                throw new HttpStatusException("EntityErrorRetrieve:AcknowledgeCode", codeResult.HttpStatusCode);
            }

            var codeEntity = codeResult.Entity;

            if (codeEntity.ReqDeviceId != identity.ClientDeviceId || codeEntity.ReqSessionId != identity.ClientSessionId)
            {
                throw new HttpStatusException(
                          $"NotMatch:Session(OriginalRequestDeviceId={codeEntity.ReqDeviceId}, IdentityDeviceId={identity.ClientDeviceId}, OriginalRequestSessionId={codeEntity.ReqSessionId}, IdentitySessionId={identity.ClientSessionId})")
                      {
                          Status = StatusCode.NotFound
                      }
            }
            ;

            if (codeEntity.ExpireIn < nowTicks)
            {
                throw new HttpStatusException("Expired:AcknowledgeCode")
                      {
                          Status = StatusCode.NotFound
                      }
            }
            ;

            if (codeEntity.Status == (int)StatusCode.Pending)
            {
                return new UserAuthenticationToken {
                           Validated = false
                }
            }
            ;
            if (codeEntity.Status != (int)StatusCode.Confirmed)
            {
                throw new HttpStatusException($"EntityErrorStatus:AcknowledgeCode(Status={codeEntity.Status})", codeEntity.Status)
                      {
                          Status = StatusCode.NotFound
                      }
            }
            ;

            codeEntity.Status = (int)StatusCode.Expired;

            var mergeResult = await table.MergeAsync(codeEntity);

            if (mergeResult >= 400)
            {
                throw new HttpStatusException("EntityErrorUpdate:AcknowledgeCode", mergeResult);
            }

            return(await CreateUserTokenAsync(identity, codeEntity.AckBy, UserVerificationLevel.StrongSignIn));
        }
        private async Task <IUserAuthenticationToken> TryGetTokenByDirectLoginCodeAsync(ISessionIdentity identity, IGetUserAuthenticationCodeRequest request)
        {
            if (string.IsNullOrEmpty(request.Code) || request.Code.Length != 40)
            {
                throw new HttpStatusException($"BadRequest:GetUserAuthenticationCodeRequest.Code({request.Code})")
                      {
                          Status = StatusCode.BadRequest
                      }
            }
            ;

            var table = tableClient.GetTableReference(DirectLoginCodeTableName);

            var now      = DateTime.UtcNow;
            var nowTicks = now.Ticks;

            var codeResult = await table.RetrieveAsync <DirectLoginCodeEntity>(request.Code.Substring(0, 8), request.Code);

            if (codeResult.HttpStatusCode == 404)
            {
                throw new HttpStatusException("EntityNotFound:DirectLoginCode", codeResult.HttpStatusCode)
                      {
                          Status = StatusCode.NotFound
                      }
            }
            ;
            if (codeResult.HttpStatusCode >= 400)
            {
                throw new HttpStatusException("EntityErrorRetrieve:DirectLoginCode", codeResult.HttpStatusCode);
            }

            var codeEntity = codeResult.Entity;

            if (codeEntity.ExpireIn < nowTicks)
            {
                throw new HttpStatusException("Expired:DirectLoginCode")
                      {
                          Status = StatusCode.NotFound
                      }
            }
            ;
            if (codeEntity.Status != (int)StatusCode.Confirmed)
            {
                throw new HttpStatusException($"EntityErrorStatus:DirectLoginCode(Status={codeEntity.Status})", codeEntity.Status)
                      {
                          Status = StatusCode.NotFound
                      }
            }
            ;

            codeEntity.Status = (int)StatusCode.Expired;
            var mergeResult = await table.MergeAsync(codeEntity);

            if (mergeResult >= 400)
            {
                throw new HttpStatusException("EntityErrorUpdate:DirectLoginCode", mergeResult);
            }

            return(await CreateUserTokenAsync(identity, codeEntity.TargetUser, UserVerificationLevel.StrongSignIn));
        }
        public async Task <IUserAuthenticationToken> TryGetTokenByCodeAsync(ISessionIdentity identity, IGetUserAuthenticationCodeRequest request)
        {
            if (identity == null || !identity.IsAuthenticated)
            {
                throw new HttpStatusException("Unauthorized:Identity")
                      {
                          Status = StatusCode.Unauthorized
                      }
            }
            ;
            if (identity.IdentityType != IdentityType.App)
            {
                throw new HttpStatusException($"NotApp:Identity({identity.IdentityType})")
                      {
                          Status = StatusCode.BadRequest
                      }
            }
            ;

            if (request.CodeType == UserAuthenticationCodeType.AcknowledgeCode)
            {
                return(await TryGetTokenByAcknowledgeCodeAsync(identity, request));
            }
            else if (request.CodeType == UserAuthenticationCodeType.DirectLoginCode)
            {
                return(await TryGetTokenByDirectLoginCodeAsync(identity, request));
            }
            else
            {
                throw new HttpStatusException($"GetUserAuthenticationCodeRequest.CodeType({request.CodeType})")
                      {
                          Status = StatusCode.BadRequest
                      };
            }
        }