summaryrefslogtreecommitdiffstats
path: root/TwoStepsAuthenticator.DotnetCore/UsedCodesManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'TwoStepsAuthenticator.DotnetCore/UsedCodesManager.cs')
-rw-r--r--TwoStepsAuthenticator.DotnetCore/UsedCodesManager.cs92
1 files changed, 88 insertions, 4 deletions
diff --git a/TwoStepsAuthenticator.DotnetCore/UsedCodesManager.cs b/TwoStepsAuthenticator.DotnetCore/UsedCodesManager.cs
index 168b934..3b21e35 100644
--- a/TwoStepsAuthenticator.DotnetCore/UsedCodesManager.cs
+++ b/TwoStepsAuthenticator.DotnetCore/UsedCodesManager.cs
@@ -1,18 +1,102 @@
using System;
using System.Collections.Generic;
+using System.Threading;
namespace TwoStepsAuthenticator
{
public class UsedCodesManager : IUsedCodesManager
{
- public void AddCode(long timestamp, string code, object user)
+ internal sealed class UsedCode
{
- throw new NotImplementedException();
+ public UsedCode(long timestamp, String code, object user)
+ {
+ this.UseDate = DateTime.Now;
+ this.Code = code;
+ this.Timestamp = timestamp;
+ this.User = user;
+ }
+
+ internal DateTime UseDate { get; private set; }
+ internal long Timestamp { get; private set; }
+ internal String Code { get; private set; }
+ internal object User { get; private set; }
+
+ public override bool Equals(object obj)
+ {
+ if (Object.ReferenceEquals(this, obj))
+ {
+ return true;
+ }
+
+ var other = obj as UsedCode;
+ return (other != null) && this.Code.Equals(other.Code) && this.Timestamp.Equals(other.Timestamp) && this.User.Equals(other.User);
+ }
+ public override string ToString()
+ {
+ return String.Format("{0}: {1}", Timestamp, Code);
+ }
+ public override int GetHashCode()
+ {
+ return Code.GetHashCode() + (Timestamp.GetHashCode() + User.GetHashCode() * 17) * 17;
+ }
}
- public bool IsCodeUsed(long timestamp, string code, object user)
+ private readonly Queue<UsedCode> codes;
+ private readonly System.Threading.ReaderWriterLockSlim rwlock = new System.Threading.ReaderWriterLockSlim();
+ private readonly Timer cleaner;
+
+ public UsedCodesManager()
{
- throw new NotImplementedException();
+ codes = new Queue<UsedCode>();
+ var delay = (int)TimeSpan.FromMinutes(5).TotalMilliseconds;
+ cleaner = new Timer(cleaner_Elapsed, null, delay, delay);
+ }
+
+ void cleaner_Elapsed(object state)
+ {
+ var timeToClean = DateTime.Now.AddMinutes(-5);
+
+ try
+ {
+ rwlock.EnterWriteLock();
+
+ while (codes.Count > 0 && codes.Peek().UseDate < timeToClean)
+ {
+ codes.Dequeue();
+ }
+ }
+ finally
+ {
+ rwlock.ExitWriteLock();
+ }
+ }
+
+ public void AddCode(long timestamp, String code, object user)
+ {
+ try
+ {
+ rwlock.EnterWriteLock();
+
+ codes.Enqueue(new UsedCode(timestamp, code, user));
+ }
+ finally
+ {
+ rwlock.ExitWriteLock();
+ }
+ }
+
+ public bool IsCodeUsed(long timestamp, String code, object user)
+ {
+ try
+ {
+ rwlock.EnterWriteLock();
+
+ return codes.Contains(new UsedCode(timestamp, code, user));
+ }
+ finally
+ {
+ rwlock.ExitWriteLock();
+ }
}
}