Skip to content

Commit

Permalink
Merge d3adea7 into cb53906
Browse files Browse the repository at this point in the history
  • Loading branch information
hawx authored Sep 2, 2024
2 parents cb53906 + d3adea7 commit 2747d6a
Show file tree
Hide file tree
Showing 47 changed files with 2,463 additions and 77 deletions.
1 change: 1 addition & 0 deletions .mockery.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ packages:
github.com/ministryofjustice/opg-modernising-lpa/internal/pay:
github.com/ministryofjustice/opg-modernising-lpa/internal/place:
github.com/ministryofjustice/opg-modernising-lpa/internal/s3:
github.com/ministryofjustice/opg-modernising-lpa/internal/scheduled:
github.com/ministryofjustice/opg-modernising-lpa/internal/search:
github.com/ministryofjustice/opg-modernising-lpa/internal/secrets:
github.com/ministryofjustice/opg-modernising-lpa/internal/sesh:
Expand Down
79 changes: 49 additions & 30 deletions cmd/mlpa/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"cmp"
"context"
"crypto/ecdsa"
"encoding/base64"
Expand All @@ -22,10 +23,10 @@ import (
"github.com/aws/aws-sdk-go-v2/config"
"github.com/golang-jwt/jwt/v5"
"github.com/gorilla/handlers"
"github.com/ministryofjustice/opg-go-common/env"
"github.com/ministryofjustice/opg-go-common/template"
"github.com/ministryofjustice/opg-modernising-lpa/internal/actor"
"github.com/ministryofjustice/opg-modernising-lpa/internal/app"
"github.com/ministryofjustice/opg-modernising-lpa/internal/donor"
"github.com/ministryofjustice/opg-modernising-lpa/internal/dynamo"
"github.com/ministryofjustice/opg-modernising-lpa/internal/event"
"github.com/ministryofjustice/opg-modernising-lpa/internal/lambda"
Expand All @@ -37,6 +38,7 @@ import (
"github.com/ministryofjustice/opg-modernising-lpa/internal/pay"
"github.com/ministryofjustice/opg-modernising-lpa/internal/place"
"github.com/ministryofjustice/opg-modernising-lpa/internal/s3"
"github.com/ministryofjustice/opg-modernising-lpa/internal/scheduled"
"github.com/ministryofjustice/opg-modernising-lpa/internal/search"
"github.com/ministryofjustice/opg-modernising-lpa/internal/secrets"
"github.com/ministryofjustice/opg-modernising-lpa/internal/sesh"
Expand Down Expand Up @@ -85,39 +87,45 @@ func main() {

func run(ctx context.Context, logger *slog.Logger) error {
var (
devMode = env.Get("DEV_MODE", "") == "1"
appPublicURL = env.Get("APP_PUBLIC_URL", "http://localhost:5050")
authRedirectBaseURL = env.Get("AUTH_REDIRECT_BASE_URL", "http://localhost:5050")
webDir = env.Get("WEB_DIR", "web")
awsBaseURL = env.Get("AWS_BASE_URL", "")
clientID = env.Get("CLIENT_ID", "client-id-value")
issuer = env.Get("ISSUER", "http://mock-onelogin:8080")
dynamoTableLpas = env.Get("DYNAMODB_TABLE_LPAS", "lpas")
notifyBaseURL = env.Get("GOVUK_NOTIFY_BASE_URL", "http://mock-notify:8080")
notifyIsProduction = env.Get("GOVUK_NOTIFY_IS_PRODUCTION", "") == "1"
ordnanceSurveyBaseURL = env.Get("ORDNANCE_SURVEY_BASE_URL", "http://mock-os-api:8080")
payBaseURL = env.Get("GOVUK_PAY_BASE_URL", "http://mock-pay:8080")
port = env.Get("APP_PORT", "8080")
xrayEnabled = env.Get("XRAY_ENABLED", "") == "1"
devMode = os.Getenv("DEV_MODE") == "1"
appPublicURL = cmp.Or(os.Getenv("APP_PUBLIC_URL"), "http://localhost:5050")
authRedirectBaseURL = cmp.Or(os.Getenv("AUTH_REDIRECT_BASE_URL"), "http://localhost:5050")
webDir = cmp.Or(os.Getenv("WEB_DIR"), "web")
awsBaseURL = os.Getenv("AWS_BASE_URL")
clientID = cmp.Or(os.Getenv("CLIENT_ID"), "client-id-value")
issuer = cmp.Or(os.Getenv("ISSUER"), "http://mock-onelogin:8080")
dynamoTableLpas = cmp.Or(os.Getenv("DYNAMODB_TABLE_LPAS"), "lpas")
notifyBaseURL = cmp.Or(os.Getenv("GOVUK_NOTIFY_BASE_URL"), "http://mock-notify:8080")
notifyIsProduction = os.Getenv("GOVUK_NOTIFY_IS_PRODUCTION") == "1"
ordnanceSurveyBaseURL = cmp.Or(os.Getenv("ORDNANCE_SURVEY_BASE_URL"), "http://mock-os-api:8080")
payBaseURL = cmp.Or(os.Getenv("GOVUK_PAY_BASE_URL"), "http://mock-pay:8080")
port = cmp.Or(os.Getenv("APP_PORT"), "8080")
xrayEnabled = os.Getenv("XRAY_ENABLED") == "1"
rumConfig = templatefn.RumConfig{
GuestRoleArn: env.Get("AWS_RUM_GUEST_ROLE_ARN", ""),
Endpoint: env.Get("AWS_RUM_ENDPOINT", ""),
ApplicationRegion: env.Get("AWS_RUM_APPLICATION_REGION", ""),
IdentityPoolID: env.Get("AWS_RUM_IDENTITY_POOL_ID", ""),
ApplicationID: env.Get("AWS_RUM_APPLICATION_ID", ""),
GuestRoleArn: os.Getenv("AWS_RUM_GUEST_ROLE_ARN"),
Endpoint: os.Getenv("AWS_RUM_ENDPOINT"),
ApplicationRegion: os.Getenv("AWS_RUM_APPLICATION_REGION"),
IdentityPoolID: os.Getenv("AWS_RUM_IDENTITY_POOL_ID"),
ApplicationID: os.Getenv("AWS_RUM_APPLICATION_ID"),
}
uidBaseURL = env.Get("UID_BASE_URL", "http://mock-uid:8080")
lpaStoreBaseURL = env.Get("LPA_STORE_BASE_URL", "http://mock-lpa-store:8080")
metadataURL = env.Get("ECS_CONTAINER_METADATA_URI_V4", "")
oneloginURL = env.Get("ONELOGIN_URL", "https://home.integration.account.gov.uk")
evidenceBucketName = env.Get("UPLOADS_S3_BUCKET_NAME", "evidence")
eventBusName = env.Get("EVENT_BUS_NAME", "default")
mockIdentityPublicKey = env.Get("MOCK_IDENTITY_PUBLIC_KEY", "")
searchEndpoint = env.Get("SEARCH_ENDPOINT", "")
searchIndexName = env.Get("SEARCH_INDEX_NAME", "lpas")
searchIndexingEnabled = env.Get("SEARCH_INDEXING_DISABLED", "") != "1"
uidBaseURL = cmp.Or(os.Getenv("UID_BASE_URL"), "http://mock-uid:8080")
lpaStoreBaseURL = cmp.Or(os.Getenv("LPA_STORE_BASE_URL"), "http://mock-lpa-store:8080")
metadataURL = os.Getenv("ECS_CONTAINER_METADATA_URI_V4")
oneloginURL = cmp.Or(os.Getenv("ONELOGIN_URL"), "https://home.integration.account.gov.uk")
evidenceBucketName = cmp.Or(os.Getenv("UPLOADS_S3_BUCKET_NAME"), "evidence")
eventBusName = cmp.Or(os.Getenv("EVENT_BUS_NAME"), "default")
mockIdentityPublicKey = os.Getenv("MOCK_IDENTITY_PUBLIC_KEY")
searchEndpoint = os.Getenv("SEARCH_ENDPOINT")
searchIndexName = cmp.Or(os.Getenv("SEARCH_INDEX_NAME"), "lpas")
searchIndexingEnabled = os.Getenv("SEARCH_INDEXING_DISABLED") != "1"
scheduledRunnerPeriod = cmp.Or(os.Getenv("SCHEDULED_RUNNER_PERIOD"), "6h")
)

scheduledRunnerPeriodDur, err := time.ParseDuration(scheduledRunnerPeriod)
if err != nil {
return err
}

staticHash, err := dirhash.HashDir(webDir+"/static", webDir, dirhash.DefaultHash)
if err != nil {
return err
Expand Down Expand Up @@ -357,6 +365,17 @@ func run(ctx context.Context, logger *slog.Logger) error {
handler = telemetry.WrapHandler(mux)
}

donorStore := donor.NewStore(lpasDynamoClient, eventClient, logger, searchClient)
scheduledStore := scheduled.NewStore(lpasDynamoClient)

runner := scheduled.NewRunner(logger, scheduledStore, donorStore, notifyClient, scheduledRunnerPeriodDur)
go func() {
if err := runner.Run(ctx); err != nil {
logger.Error("runner error", slog.Any("err", err))
os.Exit(1)
}
}()

server := &http.Server{
Addr: ":" + port,
Handler: page.Recover(tmpls.Get("error-500.gohtml"), logger, bundle, handler),
Expand Down
1 change: 1 addition & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ services:
- SEARCH_ENDPOINT=http://my-domain.eu-west-1.opensearch.localhost.localstack.cloud:4566
- SEARCH_INDEXING_ENABLED=1
- DEV_MODE=1
- SCHEDULED_RUNNER_PERIOD=1m

event-logger:
build:
Expand Down
20 changes: 12 additions & 8 deletions internal/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/ministryofjustice/opg-modernising-lpa/internal/pay"
"github.com/ministryofjustice/opg-modernising-lpa/internal/place"
"github.com/ministryofjustice/opg-modernising-lpa/internal/random"
"github.com/ministryofjustice/opg-modernising-lpa/internal/scheduled"
"github.com/ministryofjustice/opg-modernising-lpa/internal/search"
"github.com/ministryofjustice/opg-modernising-lpa/internal/sesh"
"github.com/ministryofjustice/opg-modernising-lpa/internal/sharecode"
Expand All @@ -48,22 +49,23 @@ type Logger interface {
}

type DynamoClient interface {
One(ctx context.Context, pk dynamo.PK, sk dynamo.SK, v interface{}) error
OneByPK(ctx context.Context, pk dynamo.PK, v interface{}) error
OneByPartialSK(ctx context.Context, pk dynamo.PK, partialSK dynamo.SK, v interface{}) error
AllByKeys(ctx context.Context, keys []dynamo.Keys) ([]map[string]dynamodbtypes.AttributeValue, error)
AllByPartialSK(ctx context.Context, pk dynamo.PK, partialSK dynamo.SK, v interface{}) error
LatestForActor(ctx context.Context, sk dynamo.SK, v interface{}) error
AllBySK(ctx context.Context, sk dynamo.SK, v interface{}) error
AllByKeys(ctx context.Context, keys []dynamo.Keys) ([]map[string]dynamodbtypes.AttributeValue, error)
AllKeysByPK(ctx context.Context, pk dynamo.PK) ([]dynamo.Keys, error)
Put(ctx context.Context, v interface{}) error
BatchPut(ctx context.Context, items []interface{}) error
Create(ctx context.Context, v interface{}) error
DeleteKeys(ctx context.Context, keys []dynamo.Keys) error
DeleteOne(ctx context.Context, pk dynamo.PK, sk dynamo.SK) error
Update(ctx context.Context, pk dynamo.PK, sk dynamo.SK, values map[string]dynamodbtypes.AttributeValue, expression string) error
BatchPut(ctx context.Context, items []interface{}) error
LatestForActor(ctx context.Context, sk dynamo.SK, v interface{}) error
Move(ctx context.Context, oldKeys dynamo.Keys, value any) error
One(ctx context.Context, pk dynamo.PK, sk dynamo.SK, v interface{}) error
OneByPK(ctx context.Context, pk dynamo.PK, v interface{}) error
OneByPartialSK(ctx context.Context, pk dynamo.PK, partialSK dynamo.SK, v interface{}) error
OneBySK(ctx context.Context, sk dynamo.SK, v interface{}) error
OneByUID(ctx context.Context, uid string, v interface{}) error
Put(ctx context.Context, v interface{}) error
Update(ctx context.Context, pk dynamo.PK, sk dynamo.SK, values map[string]dynamodbtypes.AttributeValue, expression string) error
WriteTransaction(ctx context.Context, transaction *dynamo.Transaction) error
}

Expand Down Expand Up @@ -107,6 +109,7 @@ func App(
organisationStore := supporter.NewOrganisationStore(lpaDynamoClient)
memberStore := supporter.NewMemberStore(lpaDynamoClient)
voucherStore := voucher.NewStore(lpaDynamoClient)
scheduledStore := scheduled.NewStore(lpaDynamoClient)
progressTracker := task.ProgressTracker{Localizer: localizer}

shareCodeSender := sharecode.NewSender(shareCodeStore, notifyClient, appPublicURL, random.String, eventClient)
Expand Down Expand Up @@ -247,6 +250,7 @@ func App(
shareCodeStore,
progressTracker,
lpaStoreResolvingService,
scheduledStore,
)

return withAppData(page.ValidateCsrf(rootMux, sessionStore, random.String, errorHandler), localizer, lang)
Expand Down
48 changes: 48 additions & 0 deletions internal/app/mock_DynamoClient_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions internal/donor/donordata/provided.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,14 @@ func (l *Provided) Under18ActorDetails() []Under18ActorDetails {
return data
}

func (l *Provided) CorrespondentEmail() string {
if l.Correspondent.Email == "" {
return l.Donor.Email
}

return l.Correspondent.Email
}

func (l *Provided) ActorAddresses() []place.Address {
var addresses []place.Address

Expand Down
15 changes: 15 additions & 0 deletions internal/donor/donordata/provided_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,21 @@ func TestUnder18ActorDetails(t *testing.T) {
}, actors)
}

func TestProvidedCorrespondentEmail(t *testing.T) {
lpa := &Provided{
Donor: Donor{Email: "donor"},
}
assert.Equal(t, "donor", lpa.CorrespondentEmail())
}

func TestProvidedCorrespondentEmailWhenCorrespondentProvided(t *testing.T) {
lpa := &Provided{
Donor: Donor{Email: "donor"},
Correspondent: Correspondent{Email: "correspondent"},
}
assert.Equal(t, "correspondent", lpa.CorrespondentEmail())
}

func TestActorAddresses(t *testing.T) {
donor := &Provided{
Donor: Donor{Address: place.Address{Line1: "1"}},
Expand Down
12 changes: 11 additions & 1 deletion internal/donor/donorpage/identity_with_one_login_callback.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ import (
"github.com/ministryofjustice/opg-modernising-lpa/internal/donor"
"github.com/ministryofjustice/opg-modernising-lpa/internal/donor/donordata"
"github.com/ministryofjustice/opg-modernising-lpa/internal/identity"
"github.com/ministryofjustice/opg-modernising-lpa/internal/scheduled"
"github.com/ministryofjustice/opg-modernising-lpa/internal/task"
)

func IdentityWithOneLoginCallback(oneLoginClient OneLoginClient, sessionStore SessionStore, donorStore DonorStore) Handler {
func IdentityWithOneLoginCallback(oneLoginClient OneLoginClient, sessionStore SessionStore, donorStore DonorStore, scheduledStore ScheduledStore) Handler {
return func(appData appcontext.Data, w http.ResponseWriter, r *http.Request, provided *donordata.Provided) error {
if provided.DonorIdentityConfirmed() {
return donor.PathOneLoginIdentityDetails.Redirect(w, r, appData, provided)
Expand Down Expand Up @@ -59,6 +60,15 @@ func IdentityWithOneLoginCallback(oneLoginClient OneLoginClient, sessionStore Se
case identity.StatusInsufficientEvidence:
return donor.PathUnableToConfirmIdentity.Redirect(w, r, appData, provided)
default:
if err := scheduledStore.Put(r.Context(), scheduled.Event{
At: userData.RetrievedAt.AddDate(0, 6, 0),
Action: scheduled.ActionExpireDonorIdentity,
TargetLpaKey: provided.PK,
TargetLpaOwnerKey: provided.SK,
}); err != nil {
return err
}

return donor.PathOneLoginIdentityDetails.Redirect(w, r, appData, provided)
}
}
Expand Down
Loading

0 comments on commit 2747d6a

Please sign in to comment.