Skip to content

Commit

Permalink
MLPAB-1278: Redirect to dashboard when OneLogin sub is linked to an L…
Browse files Browse the repository at this point in the history
…PA (#913)
  • Loading branch information
acsauk authored Dec 13, 2023
1 parent 250b51b commit f588dae
Show file tree
Hide file tree
Showing 36 changed files with 738 additions and 206 deletions.
55 changes: 23 additions & 32 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@
"filename": "cmd/mlpa/main.go",
"hashed_secret": "dc9c2ac186b77d3f4f84400225d460ddcc5940db",
"is_verified": false,
"line_number": 165
"line_number": 186
}
],
"cypress/e2e/attorney/trust-corporation.cy.js": [
Expand All @@ -127,7 +127,7 @@
"filename": "cypress/e2e/attorney/trust-corporation.cy.js",
"hashed_secret": "6740d1ecb48c5c9ca3b2a3cb1ca2f4b4d4487473",
"is_verified": false,
"line_number": 11
"line_number": 12
}
],
"cypress/e2e/certificate-provider/enter-reference-number.cy.js": [
Expand All @@ -136,7 +136,7 @@
"filename": "cypress/e2e/certificate-provider/enter-reference-number.cy.js",
"hashed_secret": "6740d1ecb48c5c9ca3b2a3cb1ca2f4b4d4487473",
"is_verified": false,
"line_number": 13
"line_number": 15
}
],
"docker/localstack/localstack-init.sh": [
Expand All @@ -154,7 +154,7 @@
"filename": "internal/notify/client_test.go",
"hashed_secret": "e4615f10410260e2f37baec79cae53739ac3d1f5",
"is_verified": false,
"line_number": 108
"line_number": 102
}
],
"internal/onelogin/client.go": [
Expand All @@ -163,51 +163,51 @@
"filename": "internal/onelogin/client.go",
"hashed_secret": "5004c13435a31d83002dd4b4c36e61290782e833",
"is_verified": false,
"line_number": 60
"line_number": 50
}
],
"internal/onelogin/client_test.go": [
"internal/onelogin/configuration_test.go": [
{
"type": "Base64 High Entropy String",
"filename": "internal/onelogin/client_test.go",
"filename": "internal/onelogin/configuration_test.go",
"hashed_secret": "202abfba0a5645bdd42c4365448acbccd996fa4b",
"is_verified": false,
"line_number": 32
"line_number": 38
},
{
"type": "Base64 High Entropy String",
"filename": "internal/onelogin/client_test.go",
"filename": "internal/onelogin/configuration_test.go",
"hashed_secret": "baf6f44796f2de09b769741c74019125d190ec10",
"is_verified": false,
"line_number": 32
"line_number": 38
},
{
"type": "Base64 High Entropy String",
"filename": "internal/onelogin/client_test.go",
"filename": "internal/onelogin/configuration_test.go",
"hashed_secret": "ce36062048bf275566cd44572e9b8938e765a7b2",
"is_verified": false,
"line_number": 32
"line_number": 38
},
{
"type": "Base64 High Entropy String",
"filename": "internal/onelogin/client_test.go",
"filename": "internal/onelogin/configuration_test.go",
"hashed_secret": "d151606c5a71f1a890ed49e96a05aca41d78430f",
"is_verified": false,
"line_number": 32
"line_number": 38
},
{
"type": "Hex High Entropy String",
"filename": "internal/onelogin/client_test.go",
"filename": "internal/onelogin/configuration_test.go",
"hashed_secret": "d2b22571923d78d2ec43c00b0ab37c26cf31dc0a",
"is_verified": false,
"line_number": 32
"line_number": 38
},
{
"type": "Hex High Entropy String",
"filename": "internal/onelogin/client_test.go",
"filename": "internal/onelogin/configuration_test.go",
"hashed_secret": "ddef058197b1e333dd8535856a8942e1a96ea975",
"is_verified": false,
"line_number": 32
"line_number": 38
}
],
"internal/onelogin/exchange_test.go": [
Expand All @@ -219,15 +219,6 @@
"line_number": 93
}
],
"internal/onelogin/user_info_test.go": [
{
"type": "Secret Keyword",
"filename": "internal/onelogin/user_info_test.go",
"hashed_secret": "feeedadaffb3ce9f8d45984cff35778d9a42339d",
"is_verified": false,
"line_number": 88
}
],
"internal/page/attorney/enter_reference_number_test.go": [
{
"type": "Hex High Entropy String",
Expand All @@ -250,14 +241,14 @@
"filename": "internal/page/certificateprovider/enter_reference_number_test.go",
"hashed_secret": "6740d1ecb48c5c9ca3b2a3cb1ca2f4b4d4487473",
"is_verified": false,
"line_number": 221
"line_number": 206
},
{
"type": "Hex High Entropy String",
"filename": "internal/page/certificateprovider/enter_reference_number_test.go",
"hashed_secret": "6c688927eafd673c7d9194b46b2b88e096e6c9f7",
"is_verified": false,
"line_number": 232
"line_number": 217
}
],
"internal/page/share_code.go": [
Expand All @@ -266,7 +257,7 @@
"filename": "internal/page/share_code.go",
"hashed_secret": "6740d1ecb48c5c9ca3b2a3cb1ca2f4b4d4487473",
"is_verified": false,
"line_number": 35
"line_number": 60
}
],
"internal/page/share_code_test.go": [
Expand All @@ -275,7 +266,7 @@
"filename": "internal/page/share_code_test.go",
"hashed_secret": "6740d1ecb48c5c9ca3b2a3cb1ca2f4b4d4487473",
"is_verified": false,
"line_number": 124
"line_number": 82
}
],
"internal/place/client.go": [
Expand Down Expand Up @@ -345,5 +336,5 @@
}
]
},
"generated_at": "2023-11-28T11:59:12Z"
"generated_at": "2023-12-12T16:55:24Z"
}
42 changes: 27 additions & 15 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -81,46 +81,58 @@ run-structurizr-export:
docker run --rm -v $(PWD)/docs/architecture/dsl/local:/usr/local/structurizr structurizr/cli \
export -workspace /usr/local/structurizr/workspace.dsl -format mermaid

scan-lpas: ##@app dumps all entries in the lpas dynamodb table
docker compose -f docker/docker-compose.yml exec localstack awslocal dynamodb scan --table-name lpas
scan-lpas: ##@dynamodb dumps all entries in the lpas dynamodb table
docker compose -f docker/docker-compose.yml exec localstack awslocal dynamodb --region eu-west-1 scan --table-name lpas

get-lpa: ##@app dumps all entries in the lpas dynamodb table that are related to the LPA id supplied e.g. get-lpa id=abc-123
docker compose -f docker/docker-compose.yml exec localstack awslocal dynamodb \
get-lpa: ##@dynamodb dumps all entries in the lpas dynamodb table that are related to the LPA id supplied e.g. get-lpa id=abc-123
docker compose -f docker/docker-compose.yml exec localstack awslocal dynamodb --region eu-west-1 \
query --table-name lpas --key-condition-expression 'PK = :pk' --expression-attribute-values '{":pk": {"S": "LPA#$(id)"}}'

get-donor-session-id: ##@app get donor session id by the LPA id supplied e.g. get-donor-session-id lpaId=abc-123
docker compose -f docker/docker-compose.yml exec localstack awslocal dynamodb \
get-donor-session-id: ##@dynamodb get donor session id by the LPA id supplied e.g. get-donor-session-id lpaId=abc-123
docker compose -f docker/docker-compose.yml exec localstack awslocal dynamodb --region eu-west-1 \
query --table-name lpas --key-condition-expression 'PK = :pk and begins_with(SK, :sk)' --expression-attribute-values '{":pk": {"S": "LPA#$(lpaId)"}, ":sk": {"S": "#DONOR#"}}' | jq -r .Items[0].SK.S | sed 's/#DONOR#//g'

get-documents: ##@app dumps all documents in the lpas dynamodb table that are related to the LPA id supplied e.g. get-documents lpaId=abc-123
docker compose -f docker/docker-compose.yml exec localstack awslocal dynamodb \
get-documents: ##@dynamodb dumps all documents in the lpas dynamodb table that are related to the LPA id supplied e.g. get-documents lpaId=abc-123
docker compose -f docker/docker-compose.yml exec localstack awslocal dynamodb --region eu-west-1 \
query --table-name lpas --key-condition-expression 'PK = :pk and begins_with(SK, :sk)' --expression-attribute-values '{":pk": {"S": "LPA#$(lpaId)"}, ":sk": {"S": "#DOCUMENT#"}}'

emit-evidence-received: ##@app emits an evidence-received event with the given LpaUID e.g. emit-evidence-received uid=abc-123
delete-all-items: ##@dynamodb deletes and recreates lpas dynamodb table
docker compose -f docker/docker-compose.yml exec localstack awslocal dynamodb --region eu-west-1 \
delete-table --table-name lpas

docker compose -f docker/docker-compose.yml exec localstack awslocal dynamodb create-table \
--region eu-west-1 \
--table-name lpas \
--attribute-definitions AttributeName=PK,AttributeType=S AttributeName=SK,AttributeType=S AttributeName=LpaUID,AttributeType=S AttributeName=UpdatedAt,AttributeType=S \
--key-schema AttributeName=PK,KeyType=HASH AttributeName=SK,KeyType=RANGE \
--provisioned-throughput ReadCapacityUnits=1000,WriteCapacityUnits=1000 \
--global-secondary-indexes file://dynamodb-lpa-gsi-schema.json

emit-evidence-received: ##@events emits an evidence-received event with the given LpaUID e.g. emit-evidence-received uid=abc-123
curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"version":"0","id":"63eb7e5f-1f10-4744-bba9-e16d327c3b98","detail-type":"evidence-received","source":"opg.poas.sirius","account":"653761790766","time":"2023-08-30T13:40:30Z","region":"eu-west-1","resources":[],"detail":{"UID":"$(uid)"}}'

emit-reduced-fee-approved: ##@app emits a reduced-fee-approved event with the given LpaUID e.g. emit-reduced-fee-approved uid=abc-123
emit-reduced-fee-approved: ##@events emits a reduced-fee-approved event with the given LpaUID e.g. emit-reduced-fee-approved uid=abc-123
curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"version":"0","id":"63eb7e5f-1f10-4744-bba9-e16d327c3b98","detail-type":"reduced-fee-approved","source":"opg.poas.sirius","account":"653761790766","time":"2023-08-30T13:40:30Z","region":"eu-west-1","resources":[],"detail":{"UID":"$(uid)"}}'

emit-reduced-fee-declined: ##@app emits a reduced-fee-declined event with the given LpaUID e.g. emit-reduced-fee-declined uid=abc-123
emit-reduced-fee-declined: ##@events emits a reduced-fee-declined event with the given LpaUID e.g. emit-reduced-fee-declined uid=abc-123
curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"version":"0","id":"63eb7e5f-1f10-4744-bba9-e16d327c3b98","detail-type":"reduced-fee-declined","source":"opg.poas.sirius","account":"653761790766","time":"2023-08-30T13:40:30Z","region":"eu-west-1","resources":[],"detail":{"UID":"$(uid)"}}'

emit-more-evidence-required: ##@app emits a more-evidence-required event with the given LpaUID e.g. emit-more-evidence-required uid=abc-123
emit-more-evidence-required: ##@events emits a more-evidence-required event with the given LpaUID e.g. emit-more-evidence-required uid=abc-123
curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"version":"0","id":"63eb7e5f-1f10-4744-bba9-e16d327c3b98","detail-type":"more-evidence-required","source":"opg.poas.sirius","account":"653761790766","time":"2023-08-30T13:40:30Z","region":"eu-west-1","resources":[],"detail":{"UID":"$(uid)"}}'

emit-object-tags-added-with-virus: ##@app emits a ObjectTagging:Put event with the given S3 key e.g. emit-object-tags-added-with-virus key=doc/key. Also ensures a tag with virus-scan-status exists on an existing object set to infected
emit-object-tags-added-with-virus: ##@events emits a ObjectTagging:Put event with the given S3 key e.g. emit-object-tags-added-with-virus key=doc/key. Also ensures a tag with virus-scan-status exists on an existing object set to infected
docker compose -f docker/docker-compose.yml exec localstack awslocal s3api \
put-object-tagging --bucket evidence --key $(key) --tagging '{"TagSet": [{ "Key": "virus-scan-status", "Value": "infected" }]}'

curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"Records":[{"eventSource":"aws:s3","eventTime":"2023-10-23T15:58:33.081Z","eventName":"ObjectTagging:Put","s3":{"bucket":{"name":"uploads-opg-modernising-lpa-eu-west-1"},"object":{"key":"$(key)"}}}]}'

emit-object-tags-added-without-virus: ##@app emits a ObjectTagging:Put event with the given S3 key e.g. emit-object-tags-added-with-virus key=doc/key. Also ensures a tag with virus-scan-status exists on an existing object set to ok
emit-object-tags-added-without-virus: ##@events emits a ObjectTagging:Put event with the given S3 key e.g. emit-object-tags-added-with-virus key=doc/key. Also ensures a tag with virus-scan-status exists on an existing object set to ok
docker compose -f docker/docker-compose.yml exec localstack awslocal s3api \
put-object-tagging --bucket evidence --key $(key) --tagging '{"TagSet": [{ "Key": "virus-scan-status", "Value": "ok" }]}'

curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"Records":[{"eventSource":"aws:s3","eventTime":"2023-10-23T15:58:33.081Z","eventName":"ObjectTagging:Put","s3":{"bucket":{"name":"uploads-opg-modernising-lpa-eu-west-1"},"object":{"key":"$(key)"}}}]}'

emit-uid-requested: ##@app emits a uid-requested event with the given detail e.g. emit-uid-requested lpaId=abc sessionId=xyz
emit-uid-requested: ##@events emits a uid-requested event with the given detail e.g. emit-uid-requested lpaId=abc sessionId=xyz
curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"version":"0","id":"63eb7e5f-1f10-4744-bba9-e16d327c3b98","detail-type":"uid-requested","source":"opg.poas.makeregister","account":"653761790766","time":"2023-08-30T13:40:30Z","region":"eu-west-1","resources":[],"detail":{"LpaID":"$(lpaId)","DonorSessionID":"$(sessionId)","Type":"pfa","Donor":{"Name":"abc","Dob":"2000-01-01","Postcode":"F1 1FF"}}}'

logs: ##@app tails logs for all containers running
Expand Down
29 changes: 26 additions & 3 deletions cmd/mock-onelogin/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type sessionData struct {
user string
nonce string
identity bool
sub string
}

type OpenIdConfig struct {
Expand Down Expand Up @@ -132,6 +133,19 @@ func authorize() http.HandlerFunc {
return
}

if r.Method == http.MethodGet {
io.WriteString(w, `<!doctype html>
<style>body { font-family: sans-serif; font-size: 21px; margin: 2rem; } label { padding: .5rem 0; display: block; } button { font-family: inherit; font-size: 21px; padding: .3rem .5rem; margin-top: 1rem; display: block; }</style>
<h1>Mock GOV.UK One Login</h1>
<form method="post">
<p>Sign in using a OneLogin sub (to ignore, leave empty)</p>
<label for="sub">OneLogin sub</label>
<input type="text" name="sub" id=f-sub />
<button type="submit">Sign in</button>
</form>`)
return
}

redirectUri := r.FormValue("redirect_uri")
if redirectUri == "" {
log.Fatal("Required query param 'redirect_uri' missing from request")
Expand All @@ -156,7 +170,9 @@ func authorize() http.HandlerFunc {
nonce: r.FormValue("nonce"),
user: r.FormValue("user"),
identity: wantsIdentity,
sub: r.FormValue("sub"),
}

u.RawQuery = q.Encode()

log.Printf("Redirecting to %s", u.String())
Expand All @@ -166,17 +182,23 @@ func authorize() http.HandlerFunc {

func userInfo(privateKey *ecdsa.PrivateKey) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
token := tokens[strings.TrimPrefix(r.Header.Get("Authorization"), "Bearer ")]

sub := randomString("sub-", 12)

if token.sub != "" {
sub = token.sub
}

userInfo := UserInfoResponse{
Sub: randomString("sub-", 12),
Sub: sub,
Email: "[email protected]",
EmailVerified: true,
Phone: "01406946277",
PhoneVerified: true,
UpdatedAt: 1311280970,
}

token := tokens[strings.TrimPrefix(r.Header.Get("Authorization"), "Bearer ")]

if token.identity {
givenName, familyName, birthDate := userDetails(token.user)

Expand Down Expand Up @@ -204,6 +226,7 @@ func userInfo(privateKey *ecdsa.PrivateKey) http.HandlerFunc {
}).SignedString(privateKey)
}

log.Printf("Logging in with sub %s", sub)
json.NewEncoder(w).Encode(userInfo)
}
}
Expand Down
1 change: 1 addition & 0 deletions cypress/e2e/attorney/trust-corporation.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ describe('As a trust corporation', () => {

// start
cy.contains('a', 'Start').click();
cy.contains('button', 'Sign in').click();

// enter reference number
cy.get('#f-reference-number').type('abcdef123456');
Expand Down
25 changes: 11 additions & 14 deletions cypress/e2e/certificate-provider/enter-reference-number.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ const { TestEmail } = require("../../support/e2e");

describe('Enter reference number', () => {
beforeEach(() => {
cy.visit('/fixtures/certificate-provider?redirect=/certificate-provider-start&use-test-code=1&email=' + TestEmail);
});
cy.visit(`/fixtures/certificate-provider?redirect=/certificate-provider-start&use-test-code=1&email=${TestEmail}`);

it('can enter a valid reference number', { pageLoadTimeout: 6000 }, () => {
cy.contains('a', 'Start').click()
cy.contains('button', 'Sign in').click();
cy.url().should('contain', '/certificate-provider-enter-reference-number')
});

it('can enter a valid reference number', { pageLoadTimeout: 6000 }, () => {
cy.checkA11yApp();

cy.get('#f-reference-number').type('abcdef123456');
Expand All @@ -17,12 +19,10 @@ describe('Enter reference number', () => {
});

it('errors when empty number', () => {
cy.contains('a', 'Start').click()
cy.contains('Save and continue').click();

cy.checkA11yApp();

cy.contains('Save and continue').click();

cy.get('.govuk-error-summary').within(() => {
cy.contains('Enter your 12 character reference number');
});
Expand All @@ -31,13 +31,11 @@ describe('Enter reference number', () => {
});

it('errors when incorrect code', () => {
cy.contains('a', 'Start').click()

cy.checkA11yApp();

cy.get('#f-reference-number').type('notATestCode');
cy.contains('Save and continue').click();

cy.checkA11yApp();

cy.get('.govuk-error-summary').within(() => {
cy.contains('The reference number you entered is incorrect, please check it and try again');
});
Expand All @@ -46,17 +44,16 @@ describe('Enter reference number', () => {
});

it('errors when incorrect code length', () => {
cy.contains('a', 'Start').click()

cy.checkA11yApp();

cy.get('#f-reference-number').type('tooShort');
cy.contains('Save and continue').click();

cy.checkA11yApp();

cy.get('.govuk-error-summary').within(() => {
cy.contains('The reference number you enter must be 12 characters');
});

cy.contains('[for=f-reference-number] ~ .govuk-error-message', 'The reference number you enter must be 12 characters');
});

});
2 changes: 1 addition & 1 deletion cypress/e2e/certificate-provider/start.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ describe('Start', () => {
cy.contains('a', 'Start').click();

if (Cypress.config().baseUrl.includes('localhost')) {
cy.url().should('contain', '/certificate-provider-enter-reference-number')
cy.url().should('contain', '/authorize')
} else {
cy.origin('https://signin.integration.account.gov.uk', () => {
cy.url().should('contain', '/')
Expand Down
Loading

0 comments on commit f588dae

Please sign in to comment.