Skip to content
This repository was archived by the owner on Oct 31, 2021. It is now read-only.

Commit fce0e81

Browse files
committed
Cleaning out old code, adding more tests.
1 parent 9f14d51 commit fce0e81

21 files changed

+665
-97
lines changed

.dockerignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Ignore everything
22
**
3+
node_modules
34

45
# Allow the golang stuff.
56
!/pkg/**

Makefile.local

+2-2
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ init-mini: info local-dependencies-maybe
8484
make deploy-redis
8585
make deploy-postgres
8686
make vault-mini
87-
make deploy-mini-application
8887
make mail-mini
88+
make deploy-mini-application
8989
make vault-token
9090
$(call infoMsg,Local environment is setup; you should be able to access the API at: https://api.$(LOCAL_DOMAIN))
9191

@@ -511,7 +511,7 @@ work-mini:
511511
@echo "\033[0;31m#################################################################################\033[0m"
512512

513513
###################### Mailhog UI ##################################
514-
mail-mini:
514+
mail-mini: $(VALUES)
515515
$(KUBECTL) apply -f $(PWD)/minikube/mailhog.yaml \
516516
--namespace $(MINIKUBE_NAMESPACE)
517517
$(KUBECTL) rollout status deploy/mail \

pkg/communication/comms.go

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package communication
2+
3+
import (
4+
"context"
5+
"github.com/monetr/rest-api/pkg/models"
6+
)
7+
8+
type VerifyEmailParams struct {
9+
Login models.Login
10+
}
11+
12+
type UserCommunication interface {
13+
SendVerificationEmail(ctx context.Context, params VerifyEmailParams) error
14+
}

pkg/communication/smtp.go

+4
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ func (s *smtpCommunication) Send(ctx context.Context, request SendEmailRequest)
5757
builder.WriteString(request.To)
5858
builder.WriteRune('\r')
5959
builder.WriteRune('\n')
60+
builder.WriteString("From: ")
61+
builder.WriteString(request.From)
62+
builder.WriteRune('\r')
63+
builder.WriteRune('\n')
6064
builder.WriteString("Subject: ")
6165
builder.WriteString(request.Subject)
6266
builder.WriteRune('\r')

pkg/communication/smtp_mini_test.go

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//+build mini
2+
3+
package communication
4+
5+
import (
6+
"context"
7+
"fmt"
8+
"github.com/monetr/rest-api/pkg/config"
9+
"github.com/monetr/rest-api/pkg/internal/testutils"
10+
"github.com/stretchr/testify/assert"
11+
"testing"
12+
)
13+
14+
func TestSmtpCommunication_Send(t *testing.T) {
15+
t.Run("simple", func(t *testing.T) {
16+
mail := NewSMTPCommunication(testutils.GetLog(t), config.SMTPClient{
17+
Enabled: true,
18+
Username: "restapi",
19+
Password: "mailpassword",
20+
Host: "mail.default.svc.cluster.local",
21+
Port: 1025,
22+
VerifyEmails: true,
23+
})
24+
25+
err := mail.Send(context.Background(), SendEmailRequest{
26+
From: fmt.Sprintf("no-reply@%s", "monetr.mini"),
27+
28+
Subject: "Verify your email address",
29+
IsHTML: true,
30+
Content: "<html><body><h1>Hello World!</h1></body></html>",
31+
})
32+
assert.NoError(t, err, "should succeed")
33+
})
34+
}

pkg/config/configuration.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,13 @@ type SMTPClient struct {
7373
Password string
7474
Host string
7575
Port int
76-
7776
VerifyEmails bool
7877
}
7978

79+
func (s SMTPClient) ShouldVerifyEmails() bool {
80+
return s.Enabled && s.VerifyEmails
81+
}
82+
8083
type SendGrid struct {
8184
Enabled bool
8285
APIKey string
@@ -93,6 +96,14 @@ type ReCAPTCHA struct {
9396
VerifyRegister bool
9497
}
9598

99+
func (r ReCAPTCHA) ShouldVerifyLogin() bool {
100+
return r.Enabled && r.VerifyLogin
101+
}
102+
103+
func (r ReCAPTCHA) ShouldVerifyRegistration() bool {
104+
return r.Enabled && r.VerifyRegister
105+
}
106+
96107
type Plaid struct {
97108
ClientID string
98109
ClientSecret string

pkg/controller/account.go

-17
This file was deleted.

pkg/controller/error.go

+8
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,17 @@ package controller
33
// SubscriptionNotActiveError is returned to the client whenever they attempt to make an API call to an endpoint that
44
// requires an active subscription.
55
type SubscriptionNotActiveError struct {
6+
// Will include a message indicating that the user's subscription is not active. Will always be returned with a 402
7+
// status code.
68
Error string `json:"error" example:"subscription is not active"`
79
}
810

11+
// MalformedJSONError is returned to the client when the request body is not valid JSON or cannot be properly parsed.
12+
type MalformedJSONError struct {
13+
// Will include a message indicating that the request body is not valid JSON.
14+
Error string `json:"error" example:"malformed json"`
15+
}
16+
917
type ApiError struct {
1018
Error string `json:"error" example:"something went wrong on our end"`
1119
}

pkg/controller/jobs.go

-29
This file was deleted.

pkg/controller/links.go

+39-38
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package controller
22

33
import (
44
"github.com/kataras/iris/v12"
5-
"github.com/kataras/iris/v12/context"
65
"github.com/monetr/rest-api/pkg/models"
76
"net/http"
87
"strings"
@@ -13,40 +12,7 @@ func (c *Controller) linksController(p iris.Party) {
1312
// GET will list all the links in the current account.
1413
p.Get("/", c.getLinks)
1514
p.Post("/", c.postLinks)
16-
17-
p.Put("/{linkId:uint64}", func(ctx *context.Context) {
18-
linkId := ctx.Params().GetUint64Default("linkId", 0)
19-
if linkId == 0 {
20-
c.returnError(ctx, http.StatusBadRequest, "must specify a link Id to update")
21-
return
22-
}
23-
24-
var link models.Link
25-
if err := ctx.ReadJSON(&link); err != nil {
26-
// TODO (elliotcourant) Add tests for malformed json.
27-
c.wrapAndReturnError(ctx, err, http.StatusBadRequest, "malformed JSON")
28-
return
29-
}
30-
31-
link.LinkId = linkId
32-
33-
// We are not going to update default value or null fields. So we can simply clear these fields out to make sure
34-
// the user does not overwrite them somehow.
35-
link.CreatedByUserId = 0 // Make sure they don't change the created by userId.
36-
link.CreatedAt = time.Time{}
37-
link.InstitutionName = "" // This cannot be changed. If the user wants to set a name then they need to change the custom one.
38-
link.LinkType = 0 // Make sure they don't change the link type. This can be changed, but not by the user.
39-
link.PlaidLinkId = nil // Make sure they don't change the plaidLink.
40-
41-
repo := c.mustGetAuthenticatedRepository(ctx)
42-
43-
if err := repo.UpdateLink(&link); err != nil {
44-
c.wrapPgError(ctx, err, "could not update link")
45-
return
46-
}
47-
48-
ctx.JSON(link)
49-
})
15+
p.Put("/{linkId:uint64}", c.putLinks)
5016
}
5117

5218
// List all links
@@ -58,8 +24,9 @@ func (c *Controller) linksController(p iris.Party) {
5824
// @Security ApiKeyAuth
5925
// @Router /links [get]
6026
// @Success 200 {array} swag.LinkResponse
27+
// @Failure 402 {object} SubscriptionNotActiveError The user's subscription is not active.
6128
// @Failure 500 {object} ApiError Something went wrong on our end.
62-
func (c *Controller) getLinks(ctx *context.Context) {
29+
func (c *Controller) getLinks(ctx iris.Context) {
6330
repo := c.mustGetAuthenticatedRepository(ctx)
6431

6532
links, err := repo.GetLinks()
@@ -82,9 +49,10 @@ func (c *Controller) getLinks(ctx *context.Context) {
8249
// @Router /links [post]
8350
// @Param newLink body swag.CreateLinkRequest true "New Manual Link"
8451
// @Success 200 {object} swag.LinkResponse "Newly created manual link"
85-
// @Failure 400 {object} ApiError "Malformed JSON."
52+
// @Failure 400 {object} MalformedJSONError "Malformed JSON."
53+
// @Failure 402 {object} SubscriptionNotActiveError The user's subscription is not active.
8654
// @Failure 500 {object} ApiError "Something went wrong on our end."
87-
func (c *Controller) postLinks(ctx *context.Context) {
55+
func (c *Controller) postLinks(ctx iris.Context) {
8856
var link models.Link
8957
if err := ctx.ReadJSON(&link); err != nil {
9058
c.wrapAndReturnError(ctx, err, http.StatusBadRequest, "malformed JSON")
@@ -104,3 +72,36 @@ func (c *Controller) postLinks(ctx *context.Context) {
10472

10573
ctx.JSON(link)
10674
}
75+
76+
func (c *Controller) putLinks(ctx iris.Context) {
77+
linkId := ctx.Params().GetUint64Default("linkId", 0)
78+
if linkId == 0 {
79+
c.returnError(ctx, http.StatusBadRequest, "must specify a link Id to update")
80+
return
81+
}
82+
83+
var link models.Link
84+
if err := ctx.ReadJSON(&link); err != nil {
85+
c.wrapAndReturnError(ctx, err, http.StatusBadRequest, "malformed JSON")
86+
return
87+
}
88+
89+
link.LinkId = linkId
90+
91+
// We are not going to update default value or null fields. So we can simply clear these fields out to make sure
92+
// the user does not overwrite them somehow.
93+
link.CreatedByUserId = 0 // Make sure they don't change the created by userId.
94+
link.CreatedAt = time.Time{}
95+
link.InstitutionName = "" // This cannot be changed. If the user wants to set a name then they need to change the custom one.
96+
link.LinkType = 0 // Make sure they don't change the link type. This can be changed, but not by the user.
97+
link.PlaidLinkId = nil // Make sure they don't change the plaidLink.
98+
99+
repo := c.mustGetAuthenticatedRepository(ctx)
100+
101+
if err := repo.UpdateLink(&link); err != nil {
102+
c.wrapPgError(ctx, err, "could not update link")
103+
return
104+
}
105+
106+
ctx.JSON(link)
107+
}

pkg/controller/login.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,15 @@ func (c *Controller) loginEndpoint(ctx iris.Context) {
4141
Captcha string `json:"captcha"`
4242
}
4343
if err := ctx.ReadJSON(&loginRequest); err != nil {
44-
c.wrapAndReturnError(ctx, err, http.StatusBadRequest, "failed to decode login request")
44+
c.wrapAndReturnError(ctx, err, http.StatusBadRequest, "malformed json")
4545
return
4646
}
4747

4848
// This will take the captcha from the request and validate it if the API is
4949
// configured to do so. If it is enabled and the captcha fails then an error
5050
// is returned to the client.
51-
if err := c.validateCaptchaMaybe(c.getContext(ctx), loginRequest.Captcha); err != nil {
51+
52+
if err := c.validateLoginCaptcha(c.getContext(ctx), loginRequest.Captcha); err != nil {
5253
c.wrapAndReturnError(ctx, err, http.StatusBadRequest, "valid ReCAPTCHA is required")
5354
return
5455
}

0 commit comments

Comments
 (0)