public async Task Expired_RefreshToken()
        {
            var refreshToken = new RefreshToken
            {
                AccessToken = new Token("access_token") { Client = new Client() { ClientId = "roclient" } },
                LifeTime = 10,
                CreationTime = DateTimeOffset.UtcNow.AddSeconds(-15)
            };
            var handle = Guid.NewGuid().ToString();

            var store = new InMemoryRefreshTokenStore();
            await store.StoreAsync(handle, refreshToken);

            var client = await _clients.FindClientByIdAsync("roclient");

            var validator = Factory.CreateTokenRequestValidator(
                refreshTokens: store);

            var parameters = new NameValueCollection();
            parameters.Add(Constants.TokenRequest.GrantType, "refresh_token");
            parameters.Add(Constants.TokenRequest.RefreshToken, handle);

            var result = await validator.ValidateRequestAsync(parameters, client);

            result.IsError.Should().BeTrue();
            result.Error.Should().Be(Constants.TokenErrors.InvalidGrant);
        }
        private async Task When_refreshing_onetimeonly_absolute_token_then_raise_event_with_two_different_handlers()
        {
            // Given 
            var oldHandle = "old_handle";
            var client = new Client()
            {
                RefreshTokenUsage = TokenUsage.OneTimeOnly,
                RefreshTokenExpiration = TokenExpiration.Absolute
            };

            var refreshToken = new RefreshToken()
            {
                AccessToken = new Token("token_type")
                {
                    Client = new Client()
                }
            };

            // When
            await _defaultRefreshTokenService.UpdateRefreshTokenAsync(oldHandle, refreshToken, client);

            // Then
            _eventServiceMock.Verify(x => x.RaiseAsync<RefreshTokenRefreshDetails>(
                It.Is<Event<RefreshTokenRefreshDetails>>(p => p.Details.OldHandle == oldHandle && p.Details.NewHandle != p.Details.OldHandle)), Times.Once);
        }
        public async Task StoreAsync(string key, RefreshToken value)
        {
            var result = await Collection.ReplaceOneAsync(
                Filter.ById(key),
                _serializer.Serialize(key, value),
                PerformUpsert
                ).ConfigureAwait(false);

            Log.Debug(result.ToString);
        }
 public async Task StoreAsync(string key, RefreshToken value)
 {
     using (var s = _store.OpenAsyncSession())
     using (s.Advanced.DocumentStore.AggressivelyCache())
     {
         var toSave = Data.StoredRefreshToken.ToDbFormat(key, value);
         await s.StoreAsync(toSave);
         await s.SaveChangesAsync();
     }
 }
        public async Task<RefreshToken> Deserialize(BsonDocument doc)
        {
            var token = new RefreshToken();
            BsonValue at;
            if (doc.TryGetValue("accessToken", out at))
            {

               token.AccessToken = await _tokenSerializer.Deserialize(at.AsBsonDocument);
            }
            token.CreationTime = doc.GetValueOrDefault("creationTime", token.CreationTime);
            token.LifeTime = doc.GetValueOrDefault("lifetime", token.LifeTime);
            token.Version = doc.GetValueOrDefault("version", token.Version);
            return token;
        }
 internal static StoredRefreshToken ToDbFormat(string key, RefreshToken refreshToken)
 {
     return new StoredRefreshToken
     {
         Id = "refreshtokens/" + key,
         ClientId = refreshToken.ClientId,
         Scopes = refreshToken.Scopes,
         CreationTime = refreshToken.CreationTime,
         LifeTime = refreshToken.LifeTime,
         SubjectId = refreshToken.SubjectId,
         Version = refreshToken.Version,
         Expires = refreshToken.CreationTime.AddSeconds(refreshToken.LifeTime),
         AccessToken = Data.StoredToken.ToDbFormat(refreshToken.AccessToken)
     };
 }
 public BsonDocument Serialize(string key, RefreshToken value)
 {
     var doc = new BsonDocument();
     doc["_id"] = key;
     doc["_version"] = 1;
     doc["_expires"] = value.CreationTime.AddSeconds(value.LifeTime).ToBsonDateTime();
     doc["_clientId"] = value.ClientId;
     doc["_subjectId"] = value.SubjectId;
     var accessToken = new BsonDocument();
     _tokenSerializer.Serialize(accessToken ,value.AccessToken);
     doc["accessToken"] = accessToken;
     doc["creationTime"] = value.CreationTime.ToBsonDateTime();
     doc["lifetime"] = value.LifeTime;
     doc["version"] = value.Version;
     return doc;
 }
        /// <summary>
        /// Stores the data.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public Task StoreAsync(string key, RefreshToken value)
        {
            _repository[key] = value;

            return Task.FromResult<object>(null);
        }
        public async Task Valid_RefreshToken_Request_using_Restricted_Client()
        {
            var mock = new Mock<IUserService>();
            var subjectClaim = new Claim(Constants.ClaimTypes.Subject, "foo");

            var refreshToken = new RefreshToken
            {
                AccessToken = new Token("access_token")
                {
                    Claims = new List<Claim> { subjectClaim },
                    Client = new Client { ClientId = "roclient_restricted_refresh"}
                },
                
                LifeTime = 600,
                CreationTime = DateTimeOffset.UtcNow
            };
            var handle = Guid.NewGuid().ToString();

            var store = new InMemoryRefreshTokenStore();
            await store.StoreAsync(handle, refreshToken);

            var client = await _clients.FindClientByIdAsync("roclient_restricted_refresh");

            var validator = Factory.CreateTokenRequestValidator(
                refreshTokens: store,
                userService: mock.Object);

            var parameters = new NameValueCollection();
            parameters.Add(Constants.TokenRequest.GrantType, "refresh_token");
            parameters.Add(Constants.TokenRequest.RefreshToken, handle);

            var result = await validator.ValidateRequestAsync(parameters, client);

            result.IsError.Should().BeFalse();
        }
        public void ToSimpleEntity_WhenComplexEntity_ExpectCorrectMap()
        {
            // Arrange
            var mockPropertyMapper = new Mock<IPropertyGetSettersTyped<RefreshToken>>();
            var mockClaimsPrincipalMapper = new Mock<IMapper<SimpleClaimsPrincipal, ClaimsPrincipal>>();
            var mockTokenMapper = new Mock<IMapper<SimpleToken, Token>>();

            mockClaimsPrincipalMapper.Setup(r => r.ToSimpleEntity(It.IsAny<ClaimsPrincipal>()))
                .Returns(new SimpleClaimsPrincipal());

            mockTokenMapper.Setup(r => r.ToSimpleEntity(It.IsAny<Token>())).Returns(new SimpleToken());

            mockPropertyMapper.Setup(r => r.GetGetters(It.IsAny<Type>()))
                .Returns(new Dictionary<string, Func<RefreshToken, object>>());

            var refreshTokenMappers = new RefreshTokenMappers<RefreshToken>(
                mockPropertyMapper.Object,
                mockClaimsPrincipalMapper.Object,
                mockTokenMapper.Object);

            var complexEntity = new RefreshToken
            {
                Subject = new ClaimsPrincipal(),
                CreationTime = new DateTimeOffset(new DateTime(2016, 1, 1)),
                AccessToken = new Token(),
                LifeTime = 1,
                Version = 1
            };

            // Act
            var stopwatch = Stopwatch.StartNew();
            var simpleRefreshToken = refreshTokenMappers.ToSimpleEntity(complexEntity);
            stopwatch.Stop();

            // Assert
            this.WriteTimeElapsed(stopwatch);

            Assert.That(simpleRefreshToken.Subject, Is.Not.Null);
            Assert.That(simpleRefreshToken.AccessToken, Is.Not.Null);
            Assert.That(simpleRefreshToken.CreationTime, Is.EqualTo(new DateTimeOffset(new DateTime(2016, 1, 1))));
            Assert.That(simpleRefreshToken.LifeTime, Is.EqualTo(1));
            Assert.That(simpleRefreshToken.Version, Is.EqualTo(1));
        }
        public void RefreshTokenPersists()
        {
            var subClaim = new Claim("sub", "*****@*****.**");
            var emailClaim = new Claim("email", "*****@*****.**");

            var token = new RefreshToken
            {
                AccessToken = new Token
                {
                    
                    CreationTime = DateTimeOffset.Now,
                    Audience = "aud",
                    Claims = new List<Claim> {  subClaim, emailClaim},
                    Client = new Client
                    {
                        ClientId = "cid",
                        ClientName = "cname",
                        Enabled = true,
                        SlidingRefreshTokenLifetime = 100,
                        AccessTokenType = AccessTokenType.Jwt,
                        Flow = Flows.Implicit
                    },
                    Issuer = "iss",
                    Lifetime = 1234567,
                    Type = Constants.TokenTypes.RefreshToken,
                    Version = 1,
                },
                
                CreationTime = DateTimeOffset.Now,
                Version = 1,
                LifeTime = 1234567,
                Subject = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim> { subClaim, emailClaim }))
            };

            var clients = new List<Client>
            {
                new Client
                {
                    ClientId = "cid",
                    ClientName = "cname",
                    Enabled = true,
                    SlidingRefreshTokenLifetime = 100,
                    AccessTokenType = AccessTokenType.Jwt,
                    Flow = Flows.Implicit
                }
            };
            var clientStore = new InMemoryClientStore(clients);

            var scopes = new List<Scope>
            {
                new Scope
                {
                    Description = "sdescription",
                    Name = "sname",
                    Enabled = true,
                    Emphasize = false,
                    IncludeAllClaimsForUser = true,
                    Required = false,
                    Type = ScopeType.Identity
                }
            };
            var scopeStore = new InMemoryScopeStore(scopes);

            var store = new RedisRefreshTokenStore(clientStore, scopeStore, RedisServer);
            store.StoreAsync("key2", token).Wait();

            var result = store.GetAsync("key2").Result;
            Assert.Equal(token.SubjectId, result.SubjectId);
            Assert.Equal(token.ClientId, result.ClientId);
        }
 /// <summary>
 /// Raises the refresh token refreshed event.
 /// </summary>
 /// <param name="oldHandle">The old handle.</param>
 /// <param name="newHandle">The new handle.</param>
 /// <param name="token">The token.</param>
 protected async Task RaiseRefreshTokenRefreshedEventAsync(string oldHandle, string newHandle, RefreshToken token)
 {
     await _events.RaiseSuccessfulRefreshTokenRefreshEventAsync(oldHandle, newHandle, token);
 }
        /// <summary>
        /// Creates the refresh token.
        /// </summary>
        /// <param name="subject">The subject.</param>
        /// <param name="accessToken">The access token.</param>
        /// <param name="client">The client.</param>
        /// <returns>
        /// The refresh token handle
        /// </returns>
        public virtual async Task<string> CreateRefreshTokenAsync(ClaimsPrincipal subject, Token accessToken, Client client)
        {
            Logger.Debug("Creating refresh token");

            int lifetime;
            if (client.RefreshTokenExpiration == TokenExpiration.Absolute)
            {
                Logger.Debug("Setting an absolute lifetime: " + client.AbsoluteRefreshTokenLifetime);
                lifetime = client.AbsoluteRefreshTokenLifetime;
            }
            else
            {
                Logger.Debug("Setting a sliding lifetime: " + client.SlidingRefreshTokenLifetime);
                lifetime = client.SlidingRefreshTokenLifetime;
            }

            var handle = CryptoRandom.CreateUniqueId();
            var refreshToken = new RefreshToken
            {
                CreationTime = DateTimeOffsetHelper.UtcNow,
                LifeTime = lifetime,
                AccessToken = accessToken,
                Subject = subject
            };

            await _store.StoreAsync(handle, refreshToken);

            await RaiseRefreshTokenIssuedEventAsync(handle, refreshToken);
            return handle;
        }
        public async Task Client_has_no_Resource_Scope_anymore_at_RefreshToken_Request()
        {
            var subjectClaim = new Claim(Constants.ClaimTypes.Subject, "foo");
            var resourceScope = new Claim("scope", "resource");
            var offlineAccessScope = new Claim("scope", "offline_access");

            var refreshToken = new RefreshToken
            {
                AccessToken = new Token("access_token")
                { 
                    Claims = new List<Claim> { subjectClaim, resourceScope, offlineAccessScope },

                    Client = new Client
                    {
                        ClientId = "roclient_offline_only",
                    },
                },
                LifeTime = 600,
                CreationTime = DateTimeOffset.UtcNow
            };
            var handle = Guid.NewGuid().ToString();

            var store = new InMemoryRefreshTokenStore();
            await store.StoreAsync(handle, refreshToken);

            var client = await _clients.FindClientByIdAsync("roclient_offline_only");

            var validator = Factory.CreateTokenRequestValidator(
                refreshTokens: store);

            var parameters = new NameValueCollection();
            parameters.Add(Constants.TokenRequest.GrantType, "refresh_token");
            parameters.Add(Constants.TokenRequest.RefreshToken, handle);

            var result = await validator.ValidateRequestAsync(parameters, client);

            result.IsError.Should().BeTrue();
            result.Error.Should().Be(Constants.TokenErrors.InvalidGrant);
        }
 /// <summary>
 /// Raises the refresh token issued event.
 /// </summary>
 /// <param name="handle">The handle.</param>
 /// <param name="token">The token.</param>
 protected async Task RaiseRefreshTokenIssuedEventAsync(string handle, RefreshToken token)
 {
     await _events.RaiseRefreshTokenIssuedEventAsync(handle, token);
 }
        public void StoreAsync_WhenCalled_ExpectAction()
        {
            // Arrange
            var mockCacheConfiguration = new Mock<IConfiguration<RedisCacheConfigurationEntity>>();
            mockCacheConfiguration.Setup(r => r.Get).Returns(
                new RedisCacheConfigurationEntity
                {
                    CacheDuration = 10,
                    RedisCacheDefaultPrefix = "DEFAULT",
                    UseObjectCompression = false
                });

            var jsonSettingsFactory = new JsonSettingsFactory(new CustomMappersConfiguration());

            var cacheManager = new RedisCacheManager<RefreshToken>(
                RedisHelpers.ConnectionMultiplexer,
                mockCacheConfiguration.Object,
                jsonSettingsFactory.Create());

            var refreshTokenStore = new RefreshTokenStore(
                cacheManager,
                mockCacheConfiguration.Object);

            var refreshToken = new RefreshToken
            {
                AccessToken = new Token
                {
                    Client = new Client { ClientId = "cid", },
                    Claims = new List<Claim> { new Claim("SubjectId", "sid") }
                },
                CreationTime = new DateTimeOffset(new DateTime(2016, 1, 1)),
                LifeTime = 1600,
                Version = 1,
            };

            // Act
            var stopwatch = Stopwatch.StartNew();
            refreshTokenStore.StoreAsync("KeyToStore", refreshToken).Wait();
            stopwatch.Stop();

            // Assert
            this.WriteTimeElapsed(stopwatch);

            var redisValue = RedisHelpers.ConnectionMultiplexer.GetDatabase().StringGet("DEFAULT_RTS_KeyToStore");

            Assert.That(redisValue.HasValue, Is.True);
            Console.WriteLine(redisValue);
        }
        public async Task RefreshToken_Request_with_disabled_User()
        {
            var mock = new Mock<IUserService>();
            mock.Setup(u => u.IsActiveAsync(It.IsAny<IsActiveContext>())).Callback<IsActiveContext>(ctx =>
            {
                ctx.IsActive = false;
            }).Returns(Task.FromResult(0));

            var subjectClaim = new Claim(Constants.ClaimTypes.Subject, "foo");

            var refreshToken = new RefreshToken
            {
                AccessToken = new Token("access_token")
                {
                    Claims = new List<Claim> { subjectClaim },
                    Client = new Client() { ClientId = "roclient" }
                },
                LifeTime = 600,
                CreationTime = DateTimeOffset.UtcNow
            };
            var handle = Guid.NewGuid().ToString();

            var store = new InMemoryRefreshTokenStore();
            await store.StoreAsync(handle, refreshToken);

            var client = await _clients.FindClientByIdAsync("roclient");

            var validator = Factory.CreateTokenRequestValidator(
                refreshTokens: store,
                userService: mock.Object);

            var parameters = new NameValueCollection();
            parameters.Add(Constants.TokenRequest.GrantType, "refresh_token");
            parameters.Add(Constants.TokenRequest.RefreshToken, handle);

            var result = await validator.ValidateRequestAsync(parameters, client);

            result.IsError.Should().BeTrue();
        }
        public void TestFixtureSetup()
        {
            var database = RedisHelpers.ConnectionMultiplexer.GetDatabase();

            var refreshToken = new RefreshToken
            {
                AccessToken = new Token
                {
                    Client = new Client { ClientId = "cid", },
                    Claims = new List<Claim> { new Claim("SubjectId", "sid") }
                },
                CreationTime = new DateTimeOffset(new DateTime(2016, 1, 1)),
                LifeTime = 1600,
                Version = 1,
                Subject = new ClaimsPrincipal()
            };

            var settings = new JsonSettingsFactory(new CustomMappersConfiguration()).Create();

            var serialized = JsonConvert.SerializeObject(refreshToken, settings);

            database.StringSet("DEFAULT_RTS_Existing", serialized);
            database.StringSet("DEFAULT_RTS_Delete", serialized);
        }
        /// <summary>
        /// Updates the refresh token.
        /// </summary>
        /// <param name="handle">The handle.</param>
        /// <param name="refreshToken">The refresh token.</param>
        /// <param name="client">The client.</param>
        /// <returns>
        /// The refresh token handle
        /// </returns>
        public virtual async Task<string> UpdateRefreshTokenAsync(string handle, RefreshToken refreshToken, Client client)
        {
            Logger.Debug("Updating refresh token");

            bool needsUpdate = false;
            string newHandle = handle;

            if (client.RefreshTokenUsage == TokenUsage.OneTimeOnly)
            {
                Logger.Debug("Token usage is one-time only. Generating new handle");

                // delete old one
                await _store.RemoveAsync(handle);

                // create new one
                newHandle = CryptoRandom.CreateUniqueId();
                needsUpdate = true;
            }

            if (client.RefreshTokenExpiration == TokenExpiration.Sliding)
            {
                Logger.Debug("Refresh token expiration is sliding - extending lifetime");

                // make sure we don't exceed absolute exp
                // cap it at absolute exp
                var currentLifetime = refreshToken.CreationTime.GetLifetimeInSeconds();
                Logger.Debug("Current lifetime: " + currentLifetime.ToString());

                var newLifetime = currentLifetime + client.SlidingRefreshTokenLifetime;
                Logger.Debug("New lifetime: " + newLifetime.ToString());

                if (newLifetime > client.AbsoluteRefreshTokenLifetime)
                {
                    newLifetime = client.AbsoluteRefreshTokenLifetime;
                    Logger.Debug("New lifetime exceeds absolute lifetime, capping it to " + newLifetime.ToString());
                }

                refreshToken.LifeTime = newLifetime;
                needsUpdate = true;
            }

            if (needsUpdate)
            {
                await _store.StoreAsync(newHandle, refreshToken);
                Logger.Debug("Updated refresh token in store");
            }
            else
            {
                Logger.Debug("No updates to refresh token done");
            }

            await RaiseRefreshTokenRefreshedEventAsync(handle, newHandle, refreshToken);
            Logger.Debug("No updates to refresh token done");

            return handle;
        }