コード例 #1
0
        public async Task ProcessAsync_when_user_code_collision_expect_retry()
        {
            var creationTime = DateTime.UtcNow;

            clock.UtcNowFunc = () => creationTime;

            testResult.ValidatedRequest.Client.UserCodeType = FakeUserCodeGenerator.UserCodeTypeValue;
            await deviceFlowCodeService.StoreDeviceAuthorizationAsync(FakeUserCodeGenerator.TestCollisionUserCode, new DeviceCode());

            var response = await generator.ProcessAsync(testResult, TestBaseUrl);

            response.UserCode.Should().Be(FakeUserCodeGenerator.TestUniqueUserCode);
        }
コード例 #2
0
        /// <summary>
        /// Processes the response.
        /// </summary>
        /// <param name="validationResult">The validation result.</param>
        /// <param name="baseUrl">The base URL.</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException">validationResult or Client</exception>
        /// <exception cref="ArgumentException">Value cannot be null or whitespace. - baseUrl</exception>
        public virtual async Task <DeviceAuthorizationResponse> ProcessAsync(DeviceAuthorizationRequestValidationResult validationResult, string baseUrl)
        {
            if (validationResult == null)
            {
                throw new ArgumentNullException(nameof(validationResult));
            }
            if (validationResult.ValidatedRequest.Client == null)
            {
                throw new ArgumentNullException(nameof(validationResult.ValidatedRequest.Client));
            }
            if (string.IsNullOrWhiteSpace(baseUrl))
            {
                throw new ArgumentException("Value cannot be null or whitespace.", nameof(baseUrl));
            }

            Logger.LogTrace("Creating response for device authorization request");

            var response = new DeviceAuthorizationResponse();

            // generate user_code
            var userCodeGenerator = await UserCodeService.GetGenerator(
                validationResult.ValidatedRequest.Client.UserCodeType ??
                Options.DeviceFlow.DefaultUserCodeType);

            var retryCount = 0;

            while (retryCount < userCodeGenerator.RetryLimit)
            {
                var userCode = await userCodeGenerator.GenerateAsync();

                var deviceCode = await DeviceFlowCodeService.FindByUserCodeAsync(userCode);

                if (deviceCode == null)
                {
                    response.UserCode = userCode;
                    break;
                }

                retryCount++;
            }

            if (response.UserCode == null)
            {
                throw new InvalidOperationException("Unable to create unique device flow user code");
            }

            // generate verification URIs
            response.VerificationUri = Options.UserInteraction.DeviceVerificationUrl;
            if (response.VerificationUri.IsLocalUrl())
            {
                // if url is relative, parse absolute URL
                response.VerificationUri = baseUrl.RemoveTrailingSlash() + Options.UserInteraction.DeviceVerificationUrl;
            }

            if (!string.IsNullOrWhiteSpace(Options.UserInteraction.DeviceVerificationUserCodeParameter))
            {
                response.VerificationUriComplete =
                    $"{response.VerificationUri}?{Options.UserInteraction.DeviceVerificationUserCodeParameter}={response.UserCode}";
            }

            // expiration
            response.DeviceCodeLifetime = validationResult.ValidatedRequest.Client.DeviceCodeLifetime;

            // interval
            response.Interval = Options.DeviceFlow.Interval;

            // store device request (device code & user code)
            response.DeviceCode = await DeviceFlowCodeService.StoreDeviceAuthorizationAsync(response.UserCode, new DeviceCode
            {
                ClientId        = validationResult.ValidatedRequest.Client.ClientId,
                IsOpenId        = validationResult.ValidatedRequest.IsOpenIdRequest,
                Lifetime        = response.DeviceCodeLifetime,
                CreationTime    = Clock.UtcNow.UtcDateTime,
                RequestedScopes = validationResult.ValidatedRequest.ValidatedResources.ScopeValues
            });

            return(response);
        }