Skip to content

Commit 7d640ed

Browse files
committed
Improve security logic
1 parent 437e882 commit 7d640ed

5 files changed

Lines changed: 174 additions & 15 deletions

File tree

CSF.Security/AuthenticationService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ namespace CSF.Security
3030
/// <summary>
3131
/// Abstract base type for an authentication service.
3232
/// </summary>
33-
public abstract class AuthenticationService<TEnteredCredentials,TStoredCredentials>
33+
public class AuthenticationService<TEnteredCredentials,TStoredCredentials>
3434
: IAuthenticationService<TEnteredCredentials>, IAuthenticationService
3535
{
3636
#region fields

CSF.Security/Base64KeyAndSalt.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,21 @@ namespace CSF.Security
3030
/// <summary>
3131
/// Base type for stored credentials which includes a key and salt stored as Base64-encoded strings.
3232
/// </summary>
33-
public abstract class Base64KeyAndSalt : IStoredCredentialsWithKeyAndSalt
33+
public class Base64KeyAndSalt : IStoredCredentialsWithKeyAndSalt
3434
{
3535
#region properties
3636

3737
/// <summary>
38-
/// Gets or sets the key data.
38+
/// Gets or sets the Base64-encoded representation of the stored key hash.
3939
/// </summary>
4040
/// <value>The key data.</value>
41-
public string KeyData { get; set; }
41+
public virtual string Key { get; set; }
4242

4343
/// <summary>
44-
/// Gets or sets the salt data.
44+
/// Gets or sets the Base64-encoded representation of the stored salt.
4545
/// </summary>
4646
/// <value>The salt data.</value>
47-
public string SaltData { get; set; }
47+
public virtual string Salt { get; set; }
4848

4949
#endregion
5050

@@ -56,12 +56,12 @@ public abstract class Base64KeyAndSalt : IStoredCredentialsWithKeyAndSalt
5656
/// <returns>The key as a byte array.</returns>
5757
public virtual byte[] GetKeyAsByteArray()
5858
{
59-
if(KeyData == null)
59+
if(Key == null)
6060
{
6161
return null;
6262
}
6363

64-
return Convert.FromBase64String(KeyData);
64+
return Convert.FromBase64String(Key);
6565
}
6666

6767
/// <summary>
@@ -70,12 +70,12 @@ public virtual byte[] GetKeyAsByteArray()
7070
/// <returns>The salt as a byte array.</returns>
7171
public virtual byte[] GetSaltAsByteArray()
7272
{
73-
if(SaltData == null)
73+
if(Salt == null)
7474
{
7575
return null;
7676
}
7777

78-
return Convert.FromBase64String(SaltData);
78+
return Convert.FromBase64String(Salt);
7979
}
8080

8181
#endregion

CSF.Security/BinaryKeyAndSalt.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,21 @@ namespace CSF.Security
3030
/// <summary>
3131
/// Base type for stored credentials which includes a key and salt stored as binary data.
3232
/// </summary>
33-
public abstract class BinaryKeyAndSalt : IStoredCredentialsWithKeyAndSalt
33+
public class BinaryKeyAndSalt : IStoredCredentialsWithKeyAndSalt
3434
{
3535
#region properties
3636

3737
/// <summary>
3838
/// Gets or sets the key bytes.
3939
/// </summary>
4040
/// <value>The key bytes.</value>
41-
public byte[] KeyBytes { get; set; }
41+
public virtual byte[] Key { get; set; }
4242

4343
/// <summary>
4444
/// Gets or sets the salt bytes.
4545
/// </summary>
4646
/// <value>The salt bytes.</value>
47-
public byte[] SaltBytes { get; set; }
47+
public virtual byte[] Salt { get; set; }
4848

4949
#endregion
5050

@@ -56,7 +56,7 @@ public abstract class BinaryKeyAndSalt : IStoredCredentialsWithKeyAndSalt
5656
/// <returns>The key as a byte array.</returns>
5757
public virtual byte[] GetKeyAsByteArray()
5858
{
59-
return KeyBytes;
59+
return Key;
6060
}
6161

6262
/// <summary>
@@ -65,7 +65,7 @@ public virtual byte[] GetKeyAsByteArray()
6565
/// <returns>The salt as a byte array.</returns>
6666
public virtual byte[] GetSaltAsByteArray()
6767
{
68-
return SaltBytes;
68+
return Salt;
6969
}
7070

7171
#endregion
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
//
2+
// TestAuthenticationService.cs
3+
//
4+
// Author:
5+
// Craig Fowler <craig@craigfowler.me.uk>
6+
//
7+
// Copyright (c) 2016 Craig Fowler
8+
//
9+
// Permission is hereby granted, free of charge, to any person obtaining a copy
10+
// of this software and associated documentation files (the "Software"), to deal
11+
// in the Software without restriction, including without limitation the rights
12+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
// copies of the Software, and to permit persons to whom the Software is
14+
// furnished to do so, subject to the following conditions:
15+
//
16+
// The above copyright notice and this permission notice shall be included in
17+
// all copies or substantial portions of the Software.
18+
//
19+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
// THE SOFTWARE.
26+
using System;
27+
using CSF.Security;
28+
using NUnit.Framework;
29+
using Moq;
30+
31+
namespace Test.CSF.Security
32+
{
33+
[TestFixture]
34+
public class TestAuthenticationService
35+
{
36+
#region fields
37+
38+
private Mock<ICredentialsRepository<StubEnteredCredentials,StubStoredCredentials>> _repository;
39+
private Mock<ICredentialVerifier<StubEnteredCredentials,StubStoredCredentials>> _verifier;
40+
41+
private IAuthenticationService<StubEnteredCredentials> _sut;
42+
43+
#endregion
44+
45+
#region setup
46+
47+
[SetUp]
48+
public void Setup()
49+
{
50+
_repository = new Mock<ICredentialsRepository<StubEnteredCredentials, StubStoredCredentials>>();
51+
_verifier = new Mock<ICredentialVerifier<StubEnteredCredentials, StubStoredCredentials>>();
52+
53+
_sut = new AuthenticationService<StubEnteredCredentials,StubStoredCredentials>(_repository.Object,
54+
_verifier.Object);
55+
}
56+
57+
#endregion
58+
59+
#region tests
60+
61+
[Test]
62+
public void Authenticate_returns_not_found_result_when_credentials_not_found()
63+
{
64+
// Arrange
65+
var entered = Mock.Of<StubEnteredCredentials>();
66+
67+
_repository.Setup(x => x.GetStoredCredentials(entered)).Returns((StubStoredCredentials) null);
68+
69+
// Act
70+
var result = _sut.Authenticate(entered);
71+
72+
// Assert
73+
Assert.IsFalse(result.CredentialsFound);
74+
}
75+
76+
[Test]
77+
public void Authenticate_returns_failure_result_when_credentials_not_found()
78+
{
79+
// Arrange
80+
var entered = Mock.Of<StubEnteredCredentials>();
81+
82+
_repository.Setup(x => x.GetStoredCredentials(entered)).Returns((StubStoredCredentials) null);
83+
84+
// Act
85+
var result = _sut.Authenticate(entered);
86+
87+
// Assert
88+
Assert.IsFalse(result.CredentialsVerified);
89+
}
90+
91+
[Test]
92+
public void Authenticate_returns_found_result_when_credentials_are_found()
93+
{
94+
// Arrange
95+
var entered = Mock.Of<StubEnteredCredentials>();
96+
var stored = Mock.Of<StubStoredCredentials>();
97+
98+
_repository.Setup(x => x.GetStoredCredentials(entered)).Returns(stored);
99+
100+
// Act
101+
var result = _sut.Authenticate(entered);
102+
103+
// Assert
104+
Assert.IsTrue(result.CredentialsFound);
105+
}
106+
107+
[Test]
108+
public void Authenticate_returns_failure_result_when_authentication_fails()
109+
{
110+
// Arrange
111+
var entered = Mock.Of<StubEnteredCredentials>();
112+
var stored = Mock.Of<StubStoredCredentials>();
113+
114+
_repository.Setup(x => x.GetStoredCredentials(entered)).Returns(stored);
115+
_verifier.Setup(x => x.Verify(entered, stored)).Returns(false);
116+
117+
// Act
118+
var result = _sut.Authenticate(entered);
119+
120+
// Assert
121+
Assert.IsFalse(result.CredentialsVerified);
122+
}
123+
124+
[Test]
125+
public void Authenticate_returns_success_result_when_authentication_passes()
126+
{
127+
// Arrange
128+
var entered = Mock.Of<StubEnteredCredentials>();
129+
var stored = Mock.Of<StubStoredCredentials>();
130+
131+
_repository.Setup(x => x.GetStoredCredentials(entered)).Returns(stored);
132+
_verifier.Setup(x => x.Verify(entered, stored)).Returns(true);
133+
134+
// Act
135+
var result = _sut.Authenticate(entered);
136+
137+
// Assert
138+
Assert.IsTrue(result.CredentialsVerified);
139+
}
140+
141+
#endregion
142+
143+
#region contained types
144+
145+
public class StubStoredCredentials : Base64KeyAndSalt {}
146+
147+
public class StubEnteredCredentials : ICredentialsWithPassword
148+
{
149+
public virtual byte[] GetPasswordAsByteArray()
150+
{
151+
throw new NotImplementedException();
152+
}
153+
}
154+
155+
#endregion
156+
}
157+
}
158+

Test.CSF/Test.CSF.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
<Compile Include="Collections\Legacy\TestIesiCollectionExtensions.cs" />
9797
<Compile Include="Collections\Legacy\TestReferenceSet.cs" />
9898
<Compile Include="Security\TestPBKDF2CredentialVerifier.cs" />
99+
<Compile Include="Security\TestAuthenticationService.cs" />
99100
</ItemGroup>
100101
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
101102
<ItemGroup>

0 commit comments

Comments
 (0)