Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consumer API: Password-protected Tokens #909

Merged
merged 25 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b4dc74d
feat: implement password protected tokens
NikolaVetnic Oct 14, 2024
d6487c7
Merge branch 'main' into abl-18-password-protected-tokens
mergify[bot] Oct 14, 2024
7b82a82
chore: remove unused methods
NikolaVetnic Oct 14, 2024
008b3e7
chore: remove empty line
NikolaVetnic Oct 14, 2024
c667515
Merge branch 'abl-18-password-protected-tokens' of github.com:nmshd/b…
NikolaVetnic Oct 14, 2024
b33084d
test: add tests for anonymous user fetching tokens
NikolaVetnic Oct 15, 2024
f642ee4
Merge branch 'main' into abl-18-password-protected-tokens
mergify[bot] Oct 15, 2024
8aad121
fix: add check for existing allocations to relationship template CanB…
tnotheis Oct 15, 2024
733b609
chore: add explaining comments to password checks in Token.cs
tnotheis Oct 15, 2024
470418e
refactor: don't use queryable extensions; instead use expressions in …
tnotheis Oct 15, 2024
3728499
refactor: remove redundant "when not null" check from validator
tnotheis Oct 15, 2024
9f86cd2
refactor: rename things
tnotheis Oct 15, 2024
b7de38b
fix: re-add check for "password is not null" to validators
tnotheis Oct 15, 2024
c6a8f2f
Merge branch 'main' into abl-18-password-protected-tokens
NikolaVetnic Oct 15, 2024
7cf0f69
test: add can be collected with password tests
NikolaVetnic Oct 15, 2024
6c593d2
Merge branch 'abl-18-password-protected-tokens' of github.com:nmshd/b…
NikolaVetnic Oct 15, 2024
e9d0476
test: check for status code in get multiple templates feature file
tnotheis Oct 15, 2024
b73431a
test: check for status code in get multiple tokens feature file
tnotheis Oct 15, 2024
bb6b411
fix: don't throw ArgumentNullException in ReplaceExpressionVisitor
tnotheis Oct 15, 2024
926a852
test: fix naming
tnotheis Oct 15, 2024
bebfae1
fix: use correct error message in validator tests
tnotheis Oct 15, 2024
a130ec4
fix: use correct error message in CreateToken validator tests
tnotheis Oct 15, 2024
4abc7b6
test: add tests for anonymous user
NikolaVetnic Oct 15, 2024
285f116
Merge branch 'abl-18-password-protected-tokens' of github.com:nmshd/b…
NikolaVetnic Oct 15, 2024
638832f
Merge branch 'main' into abl-18-password-protected-tokens
mergify[bot] Oct 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ User requests Relationship Templates
| rt12 | i2 | i3 | - |
| rt13 | i2 | i3 | password |
| rt14 | i2 | i3 | password |
When <activeIdentity> sends a GET request to the /RelationshipTemplate endpoint with the following payloads
When <activeIdentity> sends a GET request to the /RelationshipTemplates endpoint with the following payloads
| templateName | passwordOnGet |
| rt1 | - |
| rt2 | - |
Expand All @@ -37,7 +37,8 @@ User requests Relationship Templates
| rt12 | - |
| rt13 | password |
| rt14 | wordpass |
Then the response contains Relationship Template(s) <retreivedTemplates>
Then the response status code is 200 (OK)
And the response contains Relationship Template(s) <retreivedTemplates>

Examples:
| activeIdentity | retreivedTemplates |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ User creates a Relationship Template

Scenario: Create a personalized Relationship Template with a password
Given Identities i1 and i2
When i1 sends a POST request to the /RelationshipTemplate endpoint with password "my-password" and forIdentity i2
When i1 sends a POST request to the /RelationshipTemplates endpoint with password "my-password" and forIdentity i2
Then the response status code is 201 (Created)
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ User requests a Relationship Template
Scenario Outline: Requesting a Relationship Template in a variety of scenarios
Given Identities <givenIdentities>
And Relationship Template rt created by <templateOwner> with password "<password>" and forIdentity <forIdentity>
When <activeIdentity> sends a GET request to the /RelationshipTemplate/rt.Id endpoint with password "<passwordOnGet>"
When <activeIdentity> sends a GET request to the /RelationshipTemplates/rt.Id endpoint with password "<passwordOnGet>"
Then the response status code is <responseStatusCode>

Examples:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,46 @@ Feature: GET /Tokens

User requests multiple Tokens

Scenario: Requesting a list of own Tokens
Given Identity i
And Tokens t1 and t2 belonging to i
When i sends a GET request to the /Tokens endpoint with the ids of t1 and t2
Scenario Outline: Requesting a list of Tokens in a variety of scenarios
Given Identities i1, i2, i3 and i4
And the following Tokens
| tokenName | tokenOwner | forIdentity | password |
| rt1 | i1 | - | - |
| rt2 | i2 | - | - |
| rt3 | i1 | - | - |
| rt4 | i2 | - | - |
| rt5 | i1 | - | password |
| rt6 | i1 | - | password |
| rt7 | i2 | - | password |
| rt8 | i2 | - | password |
| rt9 | i1 | i1 | - |
| rt10 | i2 | i3 | - |
| rt11 | i2 | i2 | - |
| rt12 | i2 | i3 | - |
| rt13 | i2 | i3 | password |
| rt14 | i2 | i3 | password |
When <activeIdentity> sends a GET request to the /Tokens endpoint with the following payloads
| tokenName | passwordOnGet |
| rt1 | - |
| rt2 | - |
| rt3 | password |
| rt4 | password |
| rt5 | password |
| rt6 | - |
| rt7 | password |
| rt8 | - |
| rt9 | - |
| rt10 | - |
| rt11 | - |
| rt12 | - |
| rt13 | password |
| rt14 | wordpass |
Then the response status code is 200 (OK)
And the response contains the Tokens t1 and t2
And the response contains Token(s) <retreivedTokens>

Scenario: Requesting an own Token and a Token belonging to another identity
Given Identities i1 and i2
And Token t1 belonging to i1
And Token t2 belonging to i2
When i1 sends a GET request to the /Tokens endpoint with the ids of t1 and t2
Then the response status code is 200 (OK)
And the response contains the Tokens t1 and t2

Scenario: Requesting a list of Tokens contains tokens with ForIdentity which were created by me
Given Identities i1 and i2
And Token t belonging to i1 where ForIdentity is the address of i2
When i1 sends a GET request to the /Tokens endpoint with the ids of t
Then the response status code is 200 (Ok)
And the response contains the Token t

Scenario: Requesting a list of Tokens contains tokens with ForIdentity which were created for me
Given Identities i1 and i2
And Token t belonging to i1 where ForIdentity is the address of i2
When i2 sends a GET request to the /Tokens endpoint with the ids of t
Then the response status code is 200 (Ok)
And the response contains the Token t

Scenario: Requesting a list of Tokens does not contain tokens with ForIdentity which were created for someone else
Given Identities i1, i2 and i3
And Token t belonging to i1 where ForIdentity is the address of i2
When i3 sends a GET request to the /Tokens endpoint with the ids of t
Then the response does not contain the Token t
Examples:
| activeIdentity | retreivedTokens |
| i1 | rt1, rt2, rt3, rt4, rt5, rt6, rt7, rt9 |
| i2 | rt1, rt2, rt3, rt4, rt5, rt7, rt8, rt10, rt11, rt12, rt13, rt14 |
| i3 | rt1, rt2, rt3, rt4, rt5, rt7, rt10, rt12, rt13 |
| i4 | rt1, rt2, rt3, rt4, rt5, rt7 |
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,15 @@ User creates a Token
Scenario: Creating a Token as an anonymous user
When an anonymous user sends a POST request to the /Tokens endpoint
Then the response status code is 401 (Unauthorized)

Scenario: Creating a Token with a password
Given Identity i
When i sends a POST request to the /Tokens endpoint with the password "password"
Then the response status code is 201 (Created)
And the response contains a CreateTokenResponse

Scenario: Create a personalized Token with a password
Given Identities i1 and i2
When i1 sends a POST request to the /Tokens endpoint with password "password" and forIdentity i2
Then the response status code is 201 (Created)
And the response contains a CreateTokenResponse
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,33 @@ Feature: GET /Tokens/{id}

User requests a Token

Scenario: Requesting an own Token as an authenticated user
Given Identity i
And Token t belonging to i
When i sends a GET request to the /Tokens/{id} endpoint with t.Id
Then the response status code is 200 (OK)
And the response contains a Token
Scenario Outline: Requesting a Token in a variety of scenarios
Given Identities <givenIdentities>
And Token t created by <tokenOwner> with password "<password>" and forIdentity <forIdentity>
When <activeIdentity> sends a GET request to the /Tokens/t.Id endpoint with password "<passwordOnGet>"
Then the response status code is <responseStatusCode>

Scenario: Requesting an own Token as an anonymous user
Given Identity i
And Token t belonging to i
When an anonymous user sends a GET request to the /Tokens/{id} endpoint with t.Id
Then the response status code is 200 (OK)
And the response contains a Token

Scenario: Requesting a Token of another Identity as an authenticated user
Given Identities i1 and i2
And Token t belonging to i2
When i1 sends a GET request to the /Tokens/{id} endpoint with t.Id
Then the response status code is 200 (OK)
And the response contains a Token

Scenario: Requesting a nonexistent Token
Given Identity i
When i sends a GET request to the /Tokens/{id} endpoint with "TOKthisisnonexisting"
Then the response status code is 404 (Not Found)
And the response content contains an error with the error code "error.platform.recordNotFound"
Examples:
| givenIdentities | tokenOwner | forIdentity | password | activeIdentity | passwordOnGet | responseStatusCode | description |
| i | i | - | - | i | - | 200 (OK) | owner tries to get |
| i1 and i2 | i1 | - | - | i2 | - | 200 (OK) | non-owner tries to get |
| i | i | - | - | - | - | 200 (OK) | anonymous user tries to get |
| i | i | - | - | i | password | 200 (OK) | owner passes password even though none is set |
| i1 and i2 | i1 | - | - | i2 | password | 200 (OK) | non-owner identity passes password even though none is set |
| i | i | - | - | - | password | 200 (OK) | anonymous user passes password even though none is set |
| i | i | - | password | i | password | 200 (OK) | owner passes correct password |
| i | i | - | password | i | - | 200 (OK) | owner doesn't pass password, even though one is set |
| i1 and i2 | i1 | - | password | i2 | password | 200 (OK) | non-owner identity passes correct password |
| i1 and i2 | i1 | - | password | i2 | - | 404 (Not Found) | non-owner identity passes no password even though one is set |
| i | i | - | password | - | password | 200 (OK) | anonymous user passes correct password |
| i | i | - | password | - | - | 404 (Not Found) | anonymous user doesn't pass password, even though one is set |
| i | i | i | - | i | - | 200 (OK) | owner is forIdentity and tries to get |
| i1 and i2 | i1 | i2 | - | i1 | - | 200 (OK) | non-owner is forIdentity, creator tries to get |
| i1 and i2 | i1 | i1 | - | i2 | - | 404 (Not Found) | owner is forIdentity and non-owner tries to get |
| i | i | i | - | - | - | 404 (Not Found) | owner is forIdentity and anonymous user tries to get |
| i1 and i2 | i1 | i2 | - | i2 | - | 200 (OK) | non-owner is forIdentity and tries to get |
| i | i | i | - | - | - | 404 (Not Found) | forIdentity is set and anonymous user tries to get |
| i1 and i2 | i1 | i2 | password | i2 | password | 200 (OK) | non-owner is forIdentity and tries to get with correct password |
| i1 and i2 | i1 | i2 | password | i2 | wordpass | 404 (Not Found) | non-owner is forIdentity and tries to get with incorrect password |
| i1, i2 and i3 | i1 | i2 | password | i3 | password | 404 (Not Found) | non-owner is forIdentity, and thirdParty tries to get |
| i1 and i2 | i1 | i2 | password | - | password | 404 (Not Found) | non-owner is forIdentity, and anonymous user tries to get |
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public async Task GivenRelationshipTemplateCreatedByTokenOwnerWithPasswordAndFor
}

[Given(@"the following Relationship Templates")]
public async Task GivenRelationshipTemplatesWithTheFollowingProperties(Table table)
public async Task GivenTheFollowingRelationshipTemplates(Table table)
{
var relationshipTemplatePropertiesSet = table.CreateSet<RelationshipTemplateProperties>();

Expand Down Expand Up @@ -85,7 +85,7 @@ public async Task WhenIdentitySendsAPostRequestToTheRelationshipTemplatesEndpoin
new CreateRelationshipTemplateRequest { Content = TestData.SOME_BYTES, Password = password });
}

[When($@"{RegexFor.SINGLE_THING} sends a POST request to the /RelationshipTemplate endpoint with password ""(.*)"" and forIdentity {RegexFor.SINGLE_THING}")]
[When($@"{RegexFor.SINGLE_THING} sends a POST request to the /RelationshipTemplates endpoint with password ""(.*)"" and forIdentity {RegexFor.SINGLE_THING}")]
public async Task WhenIdentitySendsAPostRequestToTheRelationshipTemplatesEndpointWithPasswordAndForIdentity(string identityName, string passwordString, string forIdentityName)
{
var client = _clientPool.FirstForIdentityName(identityName);
Expand All @@ -96,7 +96,7 @@ public async Task WhenIdentitySendsAPostRequestToTheRelationshipTemplatesEndpoin
new CreateRelationshipTemplateRequest { Content = TestData.SOME_BYTES, ForIdentity = forClient.IdentityData!.Address, Password = password });
}

[When($@"{RegexFor.SINGLE_THING} sends a GET request to the /RelationshipTemplate/{RegexFor.SINGLE_THING}.Id endpoint with password ""([^""]*)""")]
[When($@"{RegexFor.SINGLE_THING} sends a GET request to the /RelationshipTemplates/{RegexFor.SINGLE_THING}.Id endpoint with password ""([^""]*)""")]
public async Task WhenIdentitySendsAGetRequestToTheRelationshipTemplatesIdEndpointWithPassword(string identityName, string relationshipTemplateName, string password)
{
var client = _clientPool.FirstForIdentityName(identityName);
Expand All @@ -108,8 +108,8 @@ public async Task WhenIdentitySendsAGetRequestToTheRelationshipTemplatesIdEndpoi
: await client.RelationshipTemplates.GetTemplate(relationshipTemplateId);
}

[When($@"{RegexFor.SINGLE_THING} sends a GET request to the /RelationshipTemplate endpoint with the following payloads")]
public async Task WhenISendsAGETRequestToTheRelationshipTemplateEndpointWithTheFollowingPayloads(string identityName, Table table)
[When($@"{RegexFor.SINGLE_THING} sends a GET request to the /RelationshipTemplates endpoint with the following payloads")]
public async Task WhenISendsAGETRequestToTheRelationshipTemplatesEndpointWithTheFollowingPayloads(string identityName, Table table)
{
var client = _clientPool.FirstForIdentityName(identityName);

Expand All @@ -120,7 +120,7 @@ public async Task WhenISendsAGETRequestToTheRelationshipTemplateEndpointWithTheF
var relationshipTemplateId = _relationshipTemplatesContext.CreateRelationshipTemplatesResponses[payload.TemplateName].Id;
var password = payload.PasswordOnGet == "-" ? null : Convert.FromBase64String(payload.PasswordOnGet.Trim());

return new RelationshipTemplateQueryItem { Id = relationshipTemplateId, Password = password };
return new ListRelationshipTemplatesQueryItem { Id = relationshipTemplateId, Password = password };
}).ToList();

_responseContext.WhenResponse = _listRelationshipTemplatesResponse = await client.RelationshipTemplates.ListTemplates(queryItems);
Expand Down
Loading