From 71b8066f1636427a98ad44cfc7c71d036a4303dc Mon Sep 17 00:00:00 2001 From: Martin Hansen Date: Mon, 17 Jan 2022 18:46:55 +0100 Subject: [PATCH] refactor: auth improvements --- reader/nordigen/auth.go | 90 +++++++++++++++++++++++-------------- reader/nordigen/nordigen.go | 7 ++- 2 files changed, 63 insertions(+), 34 deletions(-) diff --git a/reader/nordigen/auth.go b/reader/nordigen/auth.go index 0942f8d..1e317ef 100644 --- a/reader/nordigen/auth.go +++ b/reader/nordigen/auth.go @@ -2,6 +2,7 @@ package nordigen import ( "encoding/json" + "errors" "fmt" "log" "os" @@ -14,71 +15,94 @@ import ( const redirectPort = ":3000" -func requisitionFileLocation(endUserId string) string { - return fmt.Sprintf("%s/%s.json", ynabber.DataDir(), endUserId) +type Authorization struct { + Client nordigen.Client + BankID string + EndUserId string +} + +func (auth Authorization) Store() string { + return fmt.Sprintf("%s/%s.json", ynabber.DataDir(), auth.EndUserId) } // AuthorizationWrapper tries to get requisition from disk, if it fails it will // create a new and store that one to disk. -func AuthorizationWrapper(cli nordigen.Client, bankId string, endUserId string) (nordigen.Requisition, error) { - store := requisitionFileLocation(endUserId) - requisitionFile, err := os.ReadFile(store) - if err != nil { - log.Print("No existing requisition found, creating a new...") - requisition, err := GetAuthorization(cli, bankId, endUserId) - if err != nil { - return nordigen.Requisition{}, err - } - err = StoreAuthorization(requisition, endUserId) - if err != nil { - log.Printf("Failed to write requisition to disk: %s", err) - } - log.Printf("Requisition stored for reuse: %s", store) - return requisition, nil - } +func (auth Authorization) Wrapper() (nordigen.Requisition, error) { + requisitionFile, err := os.ReadFile(auth.Store()) + if errors.Is(err, os.ErrNotExist) { + log.Print("Requisition is not found") + return auth.CreateAndSave() + } else if err != nil { + return nordigen.Requisition{}, fmt.Errorf("ReadFile: %w", err) + } var requisition nordigen.Requisition err = json.Unmarshal(requisitionFile, &requisition) if err != nil { - return nordigen.Requisition{}, err + log.Print("Failed to parse requisition file") + return auth.CreateAndSave() + } + + switch requisition.Status { + case "EX": + log.Printf("Requisition is expired") + return auth.CreateAndSave() + case "LN": + return requisition, nil + default: + log.Printf("Unsupported requisition status: %s", requisition.Status) + return auth.CreateAndSave() + } +} + +func (auth Authorization) CreateAndSave() (nordigen.Requisition, error) { + log.Print("Creating new requisition...") + requisition, err := auth.Create() + if err != nil { + return nordigen.Requisition{}, fmt.Errorf("AuthorizationCreate: %w", err) + } + err = auth.Save(requisition) + if err != nil { + log.Printf("Failed to write requisition to disk: %s", err) } - log.Print("Found existing requisition, using it...") + log.Printf("Requisition stored for reuse: %s", auth.Store()) return requisition, nil } -func StoreAuthorization(requisition nordigen.Requisition, endUserId string) error { - store := requisitionFileLocation(endUserId) +func (auth Authorization) Save(requisition nordigen.Requisition) error { requisitionFile, err := json.Marshal(requisition) if err != nil { return err } - err = os.WriteFile(store, requisitionFile, 0644) + err = os.WriteFile(auth.Store(), requisitionFile, 0644) if err != nil { return err } return nil } -func GetAuthorization(cli nordigen.Client, bankId string, endUserId string) (nordigen.Requisition, error) { +func (auth Authorization) Create() (nordigen.Requisition, error) { requisition := nordigen.Requisition{ - Redirect: "http://localhost" + redirectPort, - Reference: strconv.Itoa(int(time.Now().Unix())), - Agreement: "", + Redirect: "http://localhost" + redirectPort, + Reference: strconv.Itoa(int(time.Now().Unix())), + Agreement: "", + InstitutionId: auth.BankID, } - r, err := cli.CreateRequisition(requisition) + r, err := auth.Client.CreateRequisition(requisition) if err != nil { - return nordigen.Requisition{}, err + return nordigen.Requisition{}, fmt.Errorf("CreateRequisition: %w", err) } - log.Printf("Initiate requisition by going to: %s", r.Redirect) + log.Printf("Initiate requisition by going to: %s", r.Link) - for r.Status == "CR" { - r, err = cli.GetRequisition(r.Id) + // Keep waiting for the user to accept the requisition + for r.Status != "LN" { + r, err = auth.Client.GetRequisition(r.Id) if err != nil { - return nordigen.Requisition{}, err + return nordigen.Requisition{}, fmt.Errorf("GetRequisition: %w", err) } time.Sleep(1 * time.Second) } diff --git a/reader/nordigen/nordigen.go b/reader/nordigen/nordigen.go index d174928..f74a47c 100644 --- a/reader/nordigen/nordigen.go +++ b/reader/nordigen/nordigen.go @@ -53,7 +53,12 @@ func BulkReader() (t []ynabber.Transaction, err error) { if err != nil { return nil, fmt.Errorf("failed to create client: %w", err) } - r, err := AuthorizationWrapper(*c, bankId, "ynabber") + Authorization := Authorization{ + Client: *c, + BankID: bankId, + EndUserId: "ynabber", + } + r, err := Authorization.Wrapper() if err != nil { return nil, fmt.Errorf("failed to authorize: %w", err) }