diff --git a/src/Core/Tokens/DataProtectorTokenFactory.cs b/src/Core/Tokens/DataProtectorTokenFactory.cs
index 17f7873ae7..8029b35547 100644
--- a/src/Core/Tokens/DataProtectorTokenFactory.cs
+++ b/src/Core/Tokens/DataProtectorTokenFactory.cs
@@ -16,6 +16,13 @@ namespace Bit.Core.Tokens
public string Protect(T data) =>
data.ToToken().ProtectWith(_dataProtector).WithPrefix(_clearTextPrefix).ToString();
+ ///
+ /// Unprotect token
+ ///
+ /// The token to parse
+ /// The tokenable type to parse to
+ /// The parsed tokenable
+ /// Throws CryptographicException if fails to unprotect
public T Unprotect(string token) =>
Tokenable.FromToken(new Token(token).RemovePrefix(_clearTextPrefix).UnprotectWith(_dataProtector).ToString());
diff --git a/src/Core/Tokens/ISymmetricKeyProtectedTokenFactory.cs b/src/Core/Tokens/ISymmetricKeyProtectedTokenFactory.cs
deleted file mode 100644
index 0766113d9e..0000000000
--- a/src/Core/Tokens/ISymmetricKeyProtectedTokenFactory.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Bit.Core.Tokens
-{
- public interface ISymmetricKeyProtectedTokenFactory where T : Tokenable
- {
- string Protect(string key, T data);
- T Unprotect(string key, string token);
- bool TryUnprotect(string key, string token, out T data);
- bool TokenValid(string key, string token);
- }
-}
diff --git a/test/Core.Test/Tokens/DataProtectorTokenFactoryTests.cs b/test/Core.Test/Tokens/DataProtectorTokenFactoryTests.cs
index 35fcd33a58..8a75a07900 100644
--- a/test/Core.Test/Tokens/DataProtectorTokenFactoryTests.cs
+++ b/test/Core.Test/Tokens/DataProtectorTokenFactoryTests.cs
@@ -1,4 +1,5 @@
-using AutoFixture;
+using System.Security.Cryptography;
+using AutoFixture;
using Bit.Core.Tokens;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
@@ -50,5 +51,78 @@ namespace Bit.Core.Test.Tokens
Assert.NotEqual(new Token(token).RemovePrefix(prefix), tokenable.ToToken());
}
+
+ [Theory, BitAutoData]
+ public void ThrowsIfUnprotectFails(TestTokenable tokenable)
+ {
+ var sutProvider = GetSutProvider();
+
+ var token = sutProvider.Sut.Protect(tokenable);
+ token += "stuff to make sure decryption fails";
+
+ Assert.Throws(() => sutProvider.Sut.Unprotect(token));
+ }
+
+ [Theory, BitAutoData]
+ public void TryUnprotect_FalseIfUnprotectFails(TestTokenable tokenable)
+ {
+ var sutProvider = GetSutProvider();
+ var token = sutProvider.Sut.Protect(tokenable) + "fail decryption";
+
+ var result = sutProvider.Sut.TryUnprotect(token, out var data);
+
+ Assert.False(result);
+ Assert.Null(data);
+ }
+
+ [Theory, BitAutoData]
+ public void TokenValid_FalseIfUnprotectFails(TestTokenable tokenable)
+ {
+ var sutProvider = GetSutProvider();
+ var token = sutProvider.Sut.Protect(tokenable) + "fail decryption";
+
+ var result = sutProvider.Sut.TokenValid(token);
+
+ Assert.False(result);
+ }
+
+
+ [Theory, BitAutoData]
+ public void TokenValid_FalseIfTokenInvalid(TestTokenable tokenable)
+ {
+ var sutProvider = GetSutProvider();
+
+ tokenable.ForceInvalid = true;
+ var token = sutProvider.Sut.Protect(tokenable);
+
+ var result = sutProvider.Sut.TokenValid(token);
+
+ Assert.False(result);
+ }
+
+ [Theory, BitAutoData]
+ public void TryUnprotect_TrueIfSuccess(TestTokenable tokenable)
+ {
+ var sutProvider = GetSutProvider();
+ var token = sutProvider.Sut.Protect(tokenable);
+
+ var result = sutProvider.Sut.TryUnprotect(token, out var data);
+
+ Assert.True(result);
+ AssertHelper.AssertPropertyEqual(tokenable, data);
+ }
+
+ [Theory, BitAutoData]
+ public void TokenValid_TrueIfSuccess(TestTokenable tokenable)
+ {
+ tokenable.ForceInvalid = false;
+ var sutProvider = GetSutProvider();
+ var token = sutProvider.Sut.Protect(tokenable);
+
+ var result = sutProvider.Sut.TokenValid(token);
+
+ Assert.True(result);
+ }
+
}
}
diff --git a/test/Core.Test/Tokens/TestTokenable.cs b/test/Core.Test/Tokens/TestTokenable.cs
index 0f2e2536c9..7e73cd5e9d 100644
--- a/test/Core.Test/Tokens/TestTokenable.cs
+++ b/test/Core.Test/Tokens/TestTokenable.cs
@@ -1,10 +1,14 @@
-using Bit.Core.Tokens;
+using System.Text.Json.Serialization;
+using Bit.Core.Tokens;
namespace Bit.Core.Test.Tokens
{
public class TestTokenable : Tokenable
{
- public override bool Valid => true;
+ public bool ForceInvalid { get; set; } = false;
+
+ [JsonIgnore]
+ public override bool Valid => !ForceInvalid;
}
public class TestExpiringTokenable : ExpiringTokenable