Skip to content

Commit

Permalink
Improve error handling of password recovery api
Browse files Browse the repository at this point in the history
  • Loading branch information
martinhpedersen committed Mar 27, 2024
1 parent 95481c4 commit 8d78c42
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 22 deletions.
9 changes: 5 additions & 4 deletions account.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package main
import (
"context"
"fmt"
"log"
"os"
"strings"

"github.com/la5nta/pat/internal/cmsapi"
Expand Down Expand Up @@ -32,7 +32,8 @@ func accountHandle(ctx context.Context, args []string) {
switch cmd, args := shiftArgs(args); cmd {
case "password.recovery.email":
if err := passwordRecoveryEmailHandle(ctx, args); err != nil {
log.Fatal(err)
fmt.Println("ERROR:", err)
os.Exit(1)
}
default:
fmt.Println("Missing argument, try 'account help'.")
Expand All @@ -55,13 +56,13 @@ func passwordRecoveryEmailHandle(ctx context.Context, args []string) error {
arg, _ := shiftArgs(args)
if arg != "" {
if err := cmsapi.PasswordRecoveryEmailSet(ctx, mycall, password, arg); err != nil {
return err
return fmt.Errorf("failed to set value: %w", err)
}
}
email, err := cmsapi.PasswordRecoveryEmailGet(ctx, mycall, password)
switch {
case err != nil:
return err
return fmt.Errorf("failed to get value: %w", err)
case strings.TrimSpace(email) == "":
email = "[not set]"
}
Expand Down
72 changes: 54 additions & 18 deletions internal/cmsapi/password_recovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
)
Expand All @@ -14,14 +15,24 @@ const (
PathAccountPasswordRecoveryEmailSet = "/account/password/recovery/email/set"
)

type responseStatus struct {
ErrorCode string
Message string
}

func (r responseStatus) errorOrNil() error {
if (r == responseStatus{}) {
return nil
}
return &r
}

func (r *responseStatus) Error() string { return r.Message }

func PasswordRecoveryEmailGet(ctx context.Context, callsign, password string) (string, error) {
url := RootURL + PathAccountPasswordRecoveryEmailGet +
"?key=" + AccessKey +
"&callsign=" + url.QueryEscape(callsign) +
"&password=" + url.QueryEscape(password)
req, _ := http.NewRequest("GET", url, nil)
req = req.WithContext(ctx)
req.Header.Set("Accept", "application/json")
req := newJSONRequest("GET", PathAccountPasswordRecoveryEmailGet,
url.Values{"callsign": []string{callsign}, "password": []string{password}},
nil).WithContext(ctx)
resp, err := http.DefaultClient.Do(req)
if err != nil {
return "", err
Expand All @@ -30,23 +41,24 @@ func PasswordRecoveryEmailGet(ctx context.Context, callsign, password string) (s
if resp.StatusCode != 200 {
return "", fmt.Errorf("Unexpected status code %d", resp.StatusCode)
}
var obj struct{ RecoveryEmail string }
return obj.RecoveryEmail, json.NewDecoder(resp.Body).Decode(&obj)
var obj struct {
RecoveryEmail string
ResponseStatus responseStatus
}
if err := json.NewDecoder(resp.Body).Decode(&obj); err != nil {
return "", err
}
return obj.RecoveryEmail, obj.ResponseStatus.errorOrNil()
}

func PasswordRecoveryEmailSet(ctx context.Context, callsign, password, email string) error {
payload, err := json.Marshal(struct{ RecoveryEmail string }{email})
if err != nil {
panic(err)
}
url := RootURL + PathAccountPasswordRecoveryEmailSet +
"?key=" + AccessKey +
"&callsign=" + url.QueryEscape(callsign) +
"&password=" + url.QueryEscape(password)
req, _ := http.NewRequest("POST", url, bytes.NewReader(payload))
req = req.WithContext(ctx)
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
req := newJSONRequest("POST", PathAccountPasswordRecoveryEmailSet,
url.Values{"callsign": []string{callsign}, "password": []string{password}},
bytes.NewReader(payload)).WithContext(ctx)
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
Expand All @@ -55,5 +67,29 @@ func PasswordRecoveryEmailSet(ctx context.Context, callsign, password, email str
if resp.StatusCode/100 != 2 {
return fmt.Errorf("Unexpected status code %d", resp.StatusCode)
}
return nil
var obj struct{ ResponseStatus responseStatus }
if err := json.NewDecoder(resp.Body).Decode(&obj); err != nil {
return err
}
return obj.ResponseStatus.errorOrNil()
}

func newJSONRequest(method string, path string, queryParams url.Values, body io.Reader) *http.Request {
url, err := url.JoinPath(RootURL, path)
if err != nil {
panic(err)
}
url += "?key=" + AccessKey
if len(queryParams) > 0 {
url += "&" + queryParams.Encode()
}
req, err := http.NewRequest(method, url, body)
if err != nil {
panic(err)
}
req.Header.Set("Accept", "application/json")
if body != nil {
req.Header.Set("Content-Type", "application/json")
}
return req
}

0 comments on commit 8d78c42

Please sign in to comment.