Skip to content

Commit 715afeb

Browse files
Dannypsmergify[bot]NikolaDmitrasinovictnotheis
authored
Personalized tokens (#796)
* refactor: extract common code to BaseStepDefinitions file * feat: add forIdentity field * fix: windows add_migration command not working * feat: personalized tokens support for GET /Tokens * chore: fix formatting * fix: Backbone.Modules.Tokens.Application.Tokens.Commands.CreateToken.CreateTokenCommand was missing required properties, including the following: forIdentity * feat: add sql server migrations * fix: CreateTokenCommand was missing required properties, including the following: forIdentity * chore: fix formatting * Update Applications/ConsumerApi/test/ConsumerApi.Tests.Integration/Features/Tokens/GET.feature Co-authored-by: Nikola Dmitrasinovic <[email protected]> * chore: code review changes * chore: update other script files for windows * chore: review changes * test: Token.CanBeCollectedBy * feat: remove conditional statement * fix: remove null suppressing * chore: rename field * chore: rename input param * chore: rename input param * chore: rename var * chore: remove unnecessary null check * chore: renema param * fix: use TestDataGenerator to get identity address * feat: extract method * refactor: improve assertion * refactor: improve code structure * refactor: improve code structure * fix: remove imput param * test: add integration test * fix: filter tokens by owner * fix: integration test * feat: remove FindAllOfOwner() * feat: add ForIdentity prop to DTO * chore: fix typo * refactor: improve code structure of TokensRepository * refactor: improve Find() of TokensRepository * Merge branch 'main' into NMSHDB-180-personalized-tokens * feat: introduce validation for ForIdentity prop * chore: remove blank lines * test: really small readability improvement * fix: validation * test: improve unit test for expression * chore: remove unnecessary check * test: add for create token validator * chore: fix formatting issues * Update Modules/Tokens/test/Tokens.Application.Tests/Tests/Tokens/CreateToken/ValidatorTests.cs Co-authored-by: Timo Notheisen <[email protected]> * format: improve crete token test structure * refactor: improve code structure of ValidatorTests * chore: rename param * chore: fix formatting issues --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: Nikola Dmitrasinovic <[email protected]> Co-authored-by: Nikola Dmitrasinovic <[email protected]> Co-authored-by: Timo Notheisen <[email protected]> Co-authored-by: Timo Notheisen <[email protected]>
1 parent 8498a97 commit 715afeb

File tree

29 files changed

+591
-126
lines changed

29 files changed

+591
-126
lines changed

Applications/ConsumerApi/test/ConsumerApi.Tests.Integration/ConsumerApi.Tests.Integration.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
</PropertyGroup>
66

77
<ItemGroup>
8-
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.7" />
8+
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.8" />
99
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
1010
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
1111
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.2" />

Applications/ConsumerApi/test/ConsumerApi.Tests.Integration/Features/Tokens/GET.feature

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,30 @@ Scenario: Requesting an own and peer Token
1717
When a GET request is sent to the Tokens endpoint with a list containing t.Id, p.Id
1818
Then the response status code is 200 (OK)
1919
And the response contains both Tokens
20+
21+
Scenario: Requesting a list of Tokens contains tokens with forIdentity which were created by me
22+
Given Identities i1 and i2
23+
And a Token t created by i1 where forIdentity is the address of i2
24+
When i1 sends a GET request to the /Tokens endpoint and passes t.id
25+
Then the response status code is 200 (Ok)
26+
And the response contains t
27+
28+
Scenario: Requesting a list of Tokens contains tokens with forIdentity which were created for me
29+
Given Identities i1 and i2
30+
And a Token t created by i1 where forIdentity is the address of i2
31+
When i2 sends a GET request to the /Tokens endpoint and passes t.id
32+
Then the response status code is 200 (Ok)
33+
And the response contains t
34+
35+
Scenario: Requesting a list of Tokens contains tokens which can be collected by me
36+
Given Identities i1 and i2
37+
And a Token t created by i1 where forIdentity is the address of i2
38+
When i1 sends a GET request to the /Tokens endpoint
39+
Then the response status code is 200 (Ok)
40+
And the response contains t
41+
42+
Scenario: Requesting a list of Tokens does not contain tokens with forIdentity which were created for someone else
43+
Given Identities i1, i2 and i3
44+
And a Token t created by i1 where forIdentity is the address of i2
45+
When i3 sends a GET request to the /Tokens endpoint and passes t.id
46+
Then the response does not contain t

Applications/ConsumerApi/test/ConsumerApi.Tests.Integration/Features/Tokens/{id}/GET.feature

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,31 @@ Scenario: Requesting a nonexistent Token as an authenticated user
4747
# | TOKnotenoughchars | Less than 20 characters |
4848
# | TOK_frfssd_fdfdsed#_ | Contains invalid characters |
4949
# | POKfdjfdjflndjkfndjk | Does not have TOK prefix |
50+
51+
52+
Scenario: Requesting a token with a specific forIdentity field using the recipient's address as the requester
53+
Given Identities i1 and i2
54+
And a Token t created by i1 where forIdentity is the address of i2
55+
When i2 sends a GET request to the /Tokens/{id} endpoint with t.id
56+
Then the response status code is 200 (Ok)
57+
And the response contains t
58+
59+
Scenario: Requesting a token with a specific forIdentity field using the creator's address as the requester
60+
Given Identities i1 and i2
61+
And a Token t created by i1 where forIdentity is the address of i2
62+
When i1 sends a GET request to the /Tokens/{id} endpoint with t.id
63+
Then the response status code is 200 (Ok)
64+
And the response contains t
65+
66+
Scenario: Requesting a token with a specific forIdentity field using the another address as the requester
67+
Given Identities i1, i2 and i3
68+
And a Token t created by i1 where forIdentity is the address of i2
69+
When i3 sends a GET request to the /Tokens/{id} endpoint with t.id
70+
Then the response status code is 404 (Not Found)
71+
72+
Scenario: Requesting a token with a specific forIdentity field using the an anonymous user as the requester
73+
Given Identities i1 and i2
74+
And the user is unauthenticated
75+
And a Token t created by i1 where forIdentity is the address of i2
76+
When a GET request is sent to the Tokens/{id} endpoint with t.Id
77+
Then the response status code is 404 (Not Found)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using Backbone.ConsumerApi.Sdk;
2+
using Backbone.ConsumerApi.Sdk.Authentication;
3+
using Backbone.ConsumerApi.Tests.Integration.Configuration;
4+
using Backbone.ConsumerApi.Tests.Integration.Support;
5+
using Microsoft.Extensions.Options;
6+
7+
namespace Backbone.ConsumerApi.Tests.Integration.StepDefinitions;
8+
9+
internal class BaseStepDefinitions
10+
{
11+
internal readonly Dictionary<string, Client> Identities = new();
12+
internal readonly HttpClient HttpClient;
13+
internal readonly ClientCredentials ClientCredentials;
14+
15+
public BaseStepDefinitions(HttpClientFactory factory, IOptions<HttpConfiguration> httpConfiguration)
16+
{
17+
HttpClient = factory.CreateClient();
18+
ClientCredentials = new ClientCredentials(httpConfiguration.Value.ClientCredentials.ClientId, httpConfiguration.Value.ClientCredentials.ClientSecret);
19+
}
20+
21+
#region Given
22+
23+
[Given(@"Identities (i[a-zA-Z0-9]*) and (i[a-zA-Z0-9]*)")]
24+
public void Given2Identities(string identity1Name, string identity2Name)
25+
{
26+
Identities[identity1Name] = Client.CreateForNewIdentity(HttpClient, ClientCredentials, Constants.DEVICE_PASSWORD).Result;
27+
Identities[identity2Name] = Client.CreateForNewIdentity(HttpClient, ClientCredentials, Constants.DEVICE_PASSWORD).Result;
28+
}
29+
30+
[Given(@"Identities (i[a-zA-Z0-9]*), (i[a-zA-Z0-9]*) and (i[a-zA-Z0-9]*)")]
31+
public void Given3Identities(string identity1Name, string identity2Name, string identity3Name)
32+
{
33+
Identities[identity1Name] = Client.CreateForNewIdentity(HttpClient, ClientCredentials, Constants.DEVICE_PASSWORD).Result;
34+
Identities[identity2Name] = Client.CreateForNewIdentity(HttpClient, ClientCredentials, Constants.DEVICE_PASSWORD).Result;
35+
Identities[identity3Name] = Client.CreateForNewIdentity(HttpClient, ClientCredentials, Constants.DEVICE_PASSWORD).Result;
36+
}
37+
38+
#endregion
39+
}

Applications/ConsumerApi/test/ConsumerApi.Tests.Integration/StepDefinitions/MessagesStepDefinitions.cs

Lines changed: 16 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
using Backbone.ConsumerApi.Tests.Integration.Configuration;
99
using Backbone.ConsumerApi.Tests.Integration.Extensions;
1010
using Backbone.ConsumerApi.Tests.Integration.Helpers;
11-
using Backbone.ConsumerApi.Tests.Integration.Support;
1211
using Backbone.Crypto;
1312
using Backbone.DevelopmentKit.Identity.ValueObjects;
1413
using Backbone.UnitTestTools.Data;
@@ -20,63 +19,40 @@ namespace Backbone.ConsumerApi.Tests.Integration.StepDefinitions;
2019
[Binding]
2120
[Scope(Feature = "POST Message")]
2221
[Scope(Feature = "GET Messages")]
23-
internal class MessagesStepDefinitions
22+
internal class MessagesStepDefinitions : BaseStepDefinitions
2423
{
25-
private readonly ClientCredentials _clientCredentials;
26-
private readonly HttpClient _httpClient;
27-
28-
private readonly Dictionary<string, Client> _identities = new();
2924
private readonly Dictionary<string, Relationship> _relationships = new();
3025
private readonly Dictionary<string, Message> _messages = new();
3126
private ApiResponse<ListMessagesResponse>? _getMessagesResponse;
3227
private ApiResponse<SendMessageResponse>? _sendMessageResponse;
3328
private IResponse? _whenResponse;
3429

35-
public MessagesStepDefinitions(HttpClientFactory factory, IOptions<HttpConfiguration> httpConfiguration)
36-
{
37-
_httpClient = factory.CreateClient();
38-
_clientCredentials = new ClientCredentials(httpConfiguration.Value.ClientCredentials.ClientId, httpConfiguration.Value.ClientCredentials.ClientSecret);
39-
}
30+
public MessagesStepDefinitions(HttpClientFactory factory, IOptions<HttpConfiguration> httpConfiguration) : base(factory, httpConfiguration) { }
4031

4132
#region Given
4233

43-
[Given(@"Identities (i[a-zA-Z0-9]*) and (i[a-zA-Z0-9]*)")]
44-
public void Given2Identities(string identity1Name, string identity2Name)
45-
{
46-
_identities[identity1Name] = Client.CreateForNewIdentity(_httpClient, _clientCredentials, Constants.DEVICE_PASSWORD).Result;
47-
_identities[identity2Name] = Client.CreateForNewIdentity(_httpClient, _clientCredentials, Constants.DEVICE_PASSWORD).Result;
48-
}
49-
50-
[Given(@"Identities (i[a-zA-Z0-9]*), (i[a-zA-Z0-9]*) and (i[a-zA-Z0-9]*)")]
51-
public void Given3Identities(string identity1Name, string identity2Name, string identity3Name)
52-
{
53-
_identities[identity1Name] = Client.CreateForNewIdentity(_httpClient, _clientCredentials, Constants.DEVICE_PASSWORD).Result;
54-
_identities[identity2Name] = Client.CreateForNewIdentity(_httpClient, _clientCredentials, Constants.DEVICE_PASSWORD).Result;
55-
_identities[identity3Name] = Client.CreateForNewIdentity(_httpClient, _clientCredentials, Constants.DEVICE_PASSWORD).Result;
56-
}
57-
5834
[Given(@"a Relationship (r[a-zA-Z0-9]*) between (i[a-zA-Z0-9]*) and (i[a-zA-Z0-9]*)")]
5935
public async Task GivenARelationshipRBetweenIAndI(string relationshipName, string identity1Name, string identity2Name)
6036
{
61-
var relationship = await Utils.EstablishRelationshipBetween(_identities[identity1Name], _identities[identity2Name]);
37+
var relationship = await Utils.EstablishRelationshipBetween(Identities[identity1Name], Identities[identity2Name]);
6238
_relationships[relationshipName] = relationship;
6339
}
6440

6541
[Given(@"(i[a-zA-Z0-9]*) has sent a Message (m[a-zA-Z0-9]*) to (i[a-zA-Z0-9]*)")]
6642
public async Task GivenIHasSentMessageTo1Recipient(string senderName, string messageName, string recipientName)
6743
{
68-
var sender = _identities[senderName];
69-
var recipient = _identities[recipientName];
44+
var sender = Identities[senderName];
45+
var recipient = Identities[recipientName];
7046

7147
_messages[messageName] = await Utils.SendMessage(sender, recipient);
7248
}
7349

7450
[Given(@"(i[a-zA-Z0-9]*) has sent a Message (m[a-zA-Z0-9]*) to (i[a-zA-Z0-9]*) and (i[a-zA-Z0-9]*)")]
7551
public async Task GivenIHasSentMessageTo2Recipients(string senderName, string messageName, string recipient1Name, string recipient2Name)
7652
{
77-
var sender = _identities[senderName];
78-
var recipient1 = _identities[recipient1Name];
79-
var recipient2 = _identities[recipient2Name];
53+
var sender = Identities[senderName];
54+
var recipient1 = Identities[recipient1Name];
55+
var recipient2 = Identities[recipient2Name];
8056

8157
_messages[messageName] = await Utils.SendMessage(sender, recipient1, recipient2);
8258
}
@@ -85,7 +61,7 @@ public async Task GivenIHasSentMessageTo2Recipients(string senderName, string me
8561
public async Task GivenRIsTerminated(string terminatorName, string relationshipName)
8662
{
8763
var relationship = _relationships[relationshipName];
88-
var terminator = _identities[terminatorName];
64+
var terminator = Identities[terminatorName];
8965

9066
var terminateRelationshipResponse = await terminator.Relationships.TerminateRelationship(relationship.Id);
9167
terminateRelationshipResponse.Should().BeASuccess();
@@ -94,7 +70,7 @@ public async Task GivenRIsTerminated(string terminatorName, string relationshipN
9470
[Given(@"(i[a-zA-Z0-9]*) has decomposed (r[a-zA-Z0-9]*)")]
9571
public async Task GivenIHasDecomposedItsRelationshipToI(string decomposerName, string relationshipName)
9672
{
97-
var decomposer = _identities[decomposerName];
73+
var decomposer = Identities[decomposerName];
9874
var relationship = _relationships[relationshipName];
9975

10076
var decomposeRelationshipResponse = await decomposer.Relationships.DecomposeRelationship(relationship.Id);
@@ -106,7 +82,7 @@ public async Task GivenIHasDecomposedItsRelationshipToI(string decomposerName, s
10682
[Given("(i[a-zA-Z0-9]*) is in status \"ToBeDeleted\"")]
10783
public async Task GivenIdentityIIsToBeDeleted(string identityName)
10884
{
109-
var identity = _identities[identityName];
85+
var identity = Identities[identityName];
11086
var startDeletionProcessResponse = await identity.Identities.StartDeletionProcess();
11187
startDeletionProcessResponse.Should().BeASuccess();
11288
}
@@ -118,16 +94,16 @@ public async Task GivenIdentityIIsToBeDeleted(string identityName)
11894
[When(@"(i[a-zA-Z0-9]*) sends a GET request to the /Messages endpoint")]
11995
public async Task WhenISendsAGETRequestToTheMessagesEndpoint(string senderName)
12096
{
121-
var sender = _identities[senderName];
97+
var sender = Identities[senderName];
12298
var getMessagesResponse = await sender.Messages.ListMessages();
12399
_whenResponse = _getMessagesResponse = getMessagesResponse;
124100
}
125101

126102
[When("(i[a-zA-Z0-9]*) sends a POST request to the /Messages endpoint with (i[a-zA-Z0-9]*) as recipient")]
127103
public async Task WhenAPostRequestIsSentToTheMessagesEndpoint(string senderName, string recipientName)
128104
{
129-
var sender = _identities[senderName];
130-
var recipient = _identities[recipientName];
105+
var sender = Identities[senderName];
106+
var recipient = Identities[recipientName];
131107

132108
var sendMessageRequest = new SendMessageRequest
133109
{
@@ -184,7 +160,7 @@ public void ThenTheResponseContainsTheMessageM(string messageName)
184160
[Then(@"the address of the recipient (i[a-zA-Z0-9]*) is anonymized")]
185161
public void ThenTheAddressOfIIsAnonymized(string anonymizedIdentityName)
186162
{
187-
var addressOfIdentityThatShouldBeAnonymized = _identities[anonymizedIdentityName].IdentityData!.Address;
163+
var addressOfIdentityThatShouldBeAnonymized = Identities[anonymizedIdentityName].IdentityData!.Address;
188164

189165
ThrowIfNull(_getMessagesResponse);
190166

@@ -225,7 +201,7 @@ public void ThenTheResponseContentIncludesAnErrorWithTheErrorCode(string errorCo
225201
[Then(@"the error contains a list of Identities to be deleted that includes (i[a-zA-Z0-9]*)")]
226202
public void ThenTheErrorContainsAListOfIdentitiesToBeDeletedThatIncludesIdentityI2(string includedIdentityName)
227203
{
228-
var includedIdentity = _identities[includedIdentityName];
204+
var includedIdentity = Identities[includedIdentityName];
229205
var data = _sendMessageResponse!.Error!.Data?.As<PeersToBeDeletedErrorData>();
230206
data.Should().NotBeNull();
231207
data!.PeersToBeDeleted.Contains(includedIdentity.IdentityData!.Address).Should().BeTrue();

0 commit comments

Comments
 (0)