Esempio n. 1
0
        /// <summary>
        /// Gets all authorization codes that matches the specified redirect uri and expires after the
        /// specified date. Called when authenticating an authorization code.
        /// </summary>
        /// <param name="redirectUri">The redirect uri.</param>
        /// <param name="expires">The expire date.</param>
        /// <returns>The authorization codes.</returns>
        public async Task <IEnumerable <IAuthorizationCode> > GetAuthorizationCodes(string redirectUri, DateTimeOffset expires)
        {
            var db = this.GetDatabase();

            var min   = expires.ToUnixTime();
            var codes = new List <IAuthorizationCode>();

            var nonExpiredKeys  = db.SortedSetRangeByScore($"{this.Configuration.AuthorizationCodePrefix}:_index:expires", min, DateTimeMax);
            var redirectUriKeys = db.HashGetAll($"{this.Configuration.AuthorizationCodePrefix}:_index:redirecturi:{redirectUri}");

            var unionKeys = nonExpiredKeys.Join(redirectUriKeys, x => x, y => y.Name, (x, y) => x);

            foreach (var key in unionKeys)
            {
                var hashEntries = await db.HashGetAllAsync(key.ToString());

                if (hashEntries.Any())
                {
                    var code = new RedisAuthorizationCode(hashEntries);

                    if (code.ValidTo > expires)
                    {
                        codes.Add(code);
                    }
                }
            }

            return(codes);
        }
Esempio n. 2
0
        /// <summary>Deletes the specified authorization code.</summary>
        /// <param name="identifier">The identifier.</param>
        /// <returns><c>True</c> if successful, <c>false</c> otherwise.</returns>
        public async Task <bool> DeleteAuthorizationCode(string identifier)
        {
            if (string.IsNullOrEmpty(identifier))
            {
                throw new ArgumentNullException(nameof(identifier));
            }

            var db   = this.GetDatabase();
            var tran = db.CreateTransaction();

            // Remove items from indexes
            tran.SortedSetRemoveAsync($"{this.Configuration.AuthorizationCodePrefix}:_index:expires", $"{this.Configuration.AuthorizationCodePrefix}:{identifier}");

            var hashEntries = await db.HashGetAllAsync(identifier);

            if (hashEntries.Any())
            {
                var code = new RedisAuthorizationCode(hashEntries);

                tran.HashDeleteAsync($"{this.Configuration.AuthorizationCodePrefix}:_index:redirecturi:{code.RedirectUri}", identifier);
            }

            // Remove key
            tran.KeyDeleteAsync($"{this.Configuration.AuthorizationCodePrefix}:{identifier}");

            return(await tran.ExecuteAsync(CommandFlags.HighPriority));
        }
Esempio n. 3
0
        /// <summary>
        /// Deletes the authorization codes that expires before the specified expire date. Called when
        /// creating an authorization code to cleanup.
        /// </summary>
        /// <param name="expires">The expire date.</param>
        /// <returns>The number of deleted codes.</returns>
        public async Task <int> DeleteAuthorizationCodes(DateTimeOffset expires)
        {
            var db   = this.GetDatabase();
            var tran = db.CreateTransaction();

            var keysToDelete = await db.SortedSetRangeByScoreAsync($"{this.Configuration.AuthorizationCodePrefix}:_index:expires", 0, expires.ToUnixTime());

            // Remove items from index
            tran.SortedSetRemoveRangeByScoreAsync($"{this.Configuration.AuthorizationCodePrefix}:_index:expires", 0, expires.ToUnixTime());

            // Remove keys
            foreach (var key in keysToDelete)
            {
                var hashEntries = await db.HashGetAllAsync(key.ToString());

                if (hashEntries.Any())
                {
                    var code = new RedisAuthorizationCode(hashEntries);

                    tran.HashDeleteAsync($"{this.Configuration.AuthorizationCodePrefix}:_index:redirecturi:{code.RedirectUri}", key);
                }

                tran.KeyDeleteAsync(key.ToString());
            }

            var result = await tran.ExecuteAsync(CommandFlags.HighPriority);

            if (result)
            {
                return(keysToDelete.Length);
            }

            return(0);
        }
Esempio n. 4
0
        /// <summary>
        /// Inserts the specified authorization code. Called when creating an authorization code.
        /// </summary>
        /// <param name="authorizationCode">The authorization code.</param>
        /// <returns>
        /// The inserted authorization code. <c>null</c> if the insertion was unsuccessful.
        /// </returns>
        public async Task <IAuthorizationCode> InsertAuthorizationCode(IAuthorizationCode authorizationCode)
        {
            var code = new RedisAuthorizationCode(authorizationCode);

            if (!code.IsValid())
            {
                throw new ArgumentException($"The authorization code is invalid: {JsonConvert.SerializeObject(code)}", nameof(authorizationCode));
            }

            var key = this.GenerateKeyPath(code);

            var db   = this.GetDatabase();
            var tran = db.CreateTransaction();

            try
            {
                this.Configuration.Log.DebugFormat("Inserting authorization code hash in key {0}", key);

                // Add hash to key
                tran.HashSetAsync(key, code.ToHashEntries());

                var expires = code.ValidTo.ToUnixTime();

                this.Configuration.Log.DebugFormat("Inserting key {0} to authorization code set with score {1}", key, expires);

                // Add key to sorted set for future reference. The score is the expire time in seconds since epoch.
                tran.SortedSetAddAsync($"{this.Configuration.AuthorizationCodePrefix}:_index:expires", key, expires);
                tran.HashSetAsync($"{this.Configuration.AuthorizationCodePrefix}:_index:redirecturi:{authorizationCode.RedirectUri}", key, expires);

                this.Configuration.Log.DebugFormat("Making key {0} expire at {1}", key, code.ValidTo);

                // Make the key expire when the code times out
                tran.KeyExpireAsync(key, code.ValidTo.UtcDateTime);

                await tran.ExecuteAsync();

                return(code);
            }
            catch (Exception ex)
            {
                this.Configuration.Log.Error("Error when inserting authorization code", ex);
            }

            return(null);
        }
Esempio n. 5
0
        /// <summary>Gets the specified authorization code.</summary>
        /// <param name="identifier">The identifier.</param>
        /// <returns>The authorization code.</returns>
        public async Task <IAuthorizationCode> GetAuthorizationCode(string identifier)
        {
            if (string.IsNullOrEmpty(identifier))
            {
                throw new ArgumentNullException(nameof(identifier));
            }

            var db  = this.GetDatabase();
            var key = $"{this.Configuration.AuthorizationCodePrefix}:{Convert.ToBase64String(Encoding.UTF8.GetBytes(identifier))}";

            var hashEntries = await db.HashGetAllAsync(key);

            if (hashEntries.Any())
            {
                var code = new RedisAuthorizationCode(hashEntries);

                return(code);
            }

            return(null);
        }
Esempio n. 6
0
 /// <summary>Generates a key.</summary>
 /// <param name="authorizationCode">The authorization code.</param>
 /// <returns>The key.</returns>
 protected string GenerateKeyPath(RedisAuthorizationCode authorizationCode)
 {
     return(this.Configuration.AuthorizationCodePrefix + ":" + Convert.ToBase64String(Encoding.UTF8.GetBytes(authorizationCode.GetIdentifier())));
 }