Skip to content

Commit 3b13dea

Browse files
authored
[BACK-3923/BACK-3925/BACK-3901] Various fixes for Abbott and twiist integrations
Summary merger including three pre-approved PRs and a merge of the latest master: - #888 - #889 - #890 Details: - Fix unexpected Abbott OAuth error code - Refactor twiist data ingestion to find TidepoolLinkID via ProviderSession - Refactor ListUserProviderSessions to ListProviderSessions - Add UserID to ProviderSessionFilter - Add LastDataSetID to Source - Update Abbott submodule - Update dependencies to resolve vulnerabilities - Update Go version to resolve vulnerabilities - Remove duplicate data within ingested data - https://tidepool.atlassian.net/browse/BACK-3925 - https://tidepool.atlassian.net/browse/BACK-3923 - https://tidepool.atlassian.net/browse/BACK-3901
2 parents 439376e + f593964 commit 3b13dea

File tree

27 files changed

+395
-413
lines changed

27 files changed

+395
-413
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ dist: jammy
55
language: go
66

77
go:
8-
- 1.24.3
8+
- 1.24.5
99

1010
services:
1111
- docker

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
ARG GOLANG_VERSION=1.24.3-alpine
1+
ARG GOLANG_VERSION=1.24.5-alpine
22
ARG MONGO_VERSION=6.0.23
33
ARG PLUGIN_VISIBILITY=public
44

auth/client/client.go

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -72,33 +72,6 @@ func NewClient(cfg *Config, authorizeAs platform.AuthorizeAs, name string, lgr l
7272
}, nil
7373
}
7474

75-
func (c *Client) ListUserProviderSessions(ctx context.Context, userID string, filter *auth.ProviderSessionFilter, pagination *page.Pagination) (auth.ProviderSessions, error) {
76-
if ctx == nil {
77-
return nil, errors.New("context is missing")
78-
}
79-
if userID == "" {
80-
return nil, errors.New("user id is missing")
81-
}
82-
if filter == nil {
83-
filter = auth.NewProviderSessionFilter()
84-
} else if err := structureValidator.New(log.LoggerFromContext(ctx)).Validate(filter); err != nil {
85-
return nil, errors.Wrap(err, "filter is invalid")
86-
}
87-
if pagination == nil {
88-
pagination = page.NewPagination()
89-
} else if err := structureValidator.New(log.LoggerFromContext(ctx)).Validate(pagination); err != nil {
90-
return nil, errors.Wrap(err, "pagination is invalid")
91-
}
92-
93-
url := c.client.ConstructURL("v1", "users", userID, "provider_sessions")
94-
providerSessions := auth.ProviderSessions{}
95-
if err := c.client.RequestData(ctx, http.MethodGet, url, []request.RequestMutator{filter, pagination}, nil, &providerSessions); err != nil {
96-
return nil, err
97-
}
98-
99-
return providerSessions, nil
100-
}
101-
10275
func (c *Client) CreateUserProviderSession(ctx context.Context, userID string, create *auth.ProviderSessionCreate) (*auth.ProviderSession, error) {
10376
if ctx == nil {
10477
return nil, errors.New("context is missing")
@@ -133,6 +106,30 @@ func (c *Client) DeleteUserProviderSessions(ctx context.Context, userID string)
133106
return c.client.RequestData(ctx, http.MethodDelete, url, nil, nil, nil)
134107
}
135108

109+
func (c *Client) ListProviderSessions(ctx context.Context, filter *auth.ProviderSessionFilter, pagination *page.Pagination) (auth.ProviderSessions, error) {
110+
if ctx == nil {
111+
return nil, errors.New("context is missing")
112+
}
113+
if filter == nil {
114+
filter = auth.NewProviderSessionFilter()
115+
} else if err := structureValidator.New(log.LoggerFromContext(ctx)).Validate(filter); err != nil {
116+
return nil, errors.Wrap(err, "filter is invalid")
117+
}
118+
if pagination == nil {
119+
pagination = page.NewPagination()
120+
} else if err := structureValidator.New(log.LoggerFromContext(ctx)).Validate(pagination); err != nil {
121+
return nil, errors.Wrap(err, "pagination is invalid")
122+
}
123+
124+
url := c.client.ConstructURL("v1", "provider_sessions")
125+
providerSessions := auth.ProviderSessions{}
126+
if err := c.client.RequestData(ctx, http.MethodGet, url, []request.RequestMutator{filter, pagination}, nil, &providerSessions); err != nil {
127+
return nil, err
128+
}
129+
130+
return providerSessions, nil
131+
}
132+
136133
func (c *Client) GetProviderSession(ctx context.Context, id string) (*auth.ProviderSession, error) {
137134
if ctx == nil {
138135
return nil, errors.New("context is missing")

auth/provider_session.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/tidepool-org/platform/request"
1414
"github.com/tidepool-org/platform/structure"
1515
structureValidator "github.com/tidepool-org/platform/structure/validator"
16+
"github.com/tidepool-org/platform/user"
1617
)
1718

1819
const (
@@ -26,16 +27,17 @@ func ProviderTypes() []string {
2627
}
2728

2829
type ProviderSessionAccessor interface {
29-
ListUserProviderSessions(ctx context.Context, userID string, filter *ProviderSessionFilter, pagination *page.Pagination) (ProviderSessions, error)
3030
CreateUserProviderSession(ctx context.Context, userID string, create *ProviderSessionCreate) (*ProviderSession, error)
3131
DeleteUserProviderSessions(ctx context.Context, userID string) error
3232

33+
ListProviderSessions(ctx context.Context, filter *ProviderSessionFilter, pagination *page.Pagination) (ProviderSessions, error)
3334
GetProviderSession(ctx context.Context, id string) (*ProviderSession, error)
3435
UpdateProviderSession(ctx context.Context, id string, update *ProviderSessionUpdate) (*ProviderSession, error)
3536
DeleteProviderSession(ctx context.Context, id string) error
3637
}
3738

3839
type ProviderSessionFilter struct {
40+
UserID *string `json:"userId,omitempty"`
3941
Type *string `json:"type,omitempty"`
4042
Name *string `json:"name,omitempty"`
4143
ExternalID *string `json:"externalId,omitempty"`
@@ -46,19 +48,24 @@ func NewProviderSessionFilter() *ProviderSessionFilter {
4648
}
4749

4850
func (p *ProviderSessionFilter) Parse(parser structure.ObjectParser) {
51+
p.UserID = parser.String("userId")
4952
p.Type = parser.String("type")
5053
p.Name = parser.String("name")
5154
p.ExternalID = parser.String("externalId")
5255
}
5356

5457
func (p *ProviderSessionFilter) Validate(validator structure.Validator) {
58+
validator.String("userId", p.UserID).Using(user.IDValidator)
5559
validator.String("type", p.Type).OneOf(ProviderTypes()...)
5660
validator.String("name", p.Name).Using(ProviderNameValidator)
5761
validator.String("externalId", p.ExternalID).Using(ProviderExternalIDValidator)
5862
}
5963

6064
func (p *ProviderSessionFilter) MutateRequest(req *http.Request) error {
6165
parameters := map[string]string{}
66+
if p.UserID != nil {
67+
parameters["userId"] = *p.UserID
68+
}
6269
if p.Type != nil {
6370
parameters["type"] = *p.Type
6471
}

auth/service/api/v1/oauth.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,10 @@ func (r *Router) UserOAuthProviderAuthorizeDelete(res rest.ResponseWriter, req *
9494
}
9595

9696
providerSessionFilter := auth.NewProviderSessionFilter()
97+
providerSessionFilter.UserID = pointer.FromString(userID)
9798
providerSessionFilter.Type = pointer.FromString(prvdr.Type())
9899
providerSessionFilter.Name = pointer.FromString(prvdr.Name())
99-
providerSessions, err := r.AuthClient().ListUserProviderSessions(ctx, userID, providerSessionFilter, page.NewPagination())
100+
providerSessions, err := r.AuthClient().ListProviderSessions(ctx, providerSessionFilter, page.NewPagination())
100101
if err != nil {
101102
responder.Error(http.StatusInternalServerError, err)
102103
return
@@ -169,7 +170,7 @@ func (r *Router) OAuthProviderRedirectGet(res rest.ResponseWriter, req *rest.Req
169170
log.LoggerFromContext(ctx).WithError(err).Error("unable to delete restricted token after oauth redirect")
170171
}
171172

172-
if errorCode := query.Get("error"); errorCode == oauth.ErrorAccessDenied {
173+
if errorCode := query.Get("error"); prvdr.IsErrorCodeAccessDenied(errorCode) {
173174
html := fmt.Sprintf(htmlOnRedirect, redirectURLDeclined.String())
174175
r.htmlOnRedirect(res, req, html)
175176
return
@@ -179,9 +180,10 @@ func (r *Router) OAuthProviderRedirectGet(res rest.ResponseWriter, req *rest.Req
179180
}
180181

181182
filter := auth.NewProviderSessionFilter()
183+
filter.UserID = pointer.FromString(restrictedToken.UserID)
182184
filter.Type = pointer.FromString(prvdr.Type())
183185
filter.Name = pointer.FromString(prvdr.Name())
184-
providerSessions, err := r.AuthClient().ListUserProviderSessions(ctx, restrictedToken.UserID, filter, nil)
186+
providerSessions, err := r.AuthClient().ListProviderSessions(ctx, filter, nil)
185187
if err != nil {
186188
r.htmlOnError(res, req, err)
187189
return
@@ -258,7 +260,7 @@ func (r *Router) oauthProviderRestrictedToken(req *http.Request, prvdr oauth.Pro
258260
func (r *Router) authenticateRestrictedToken(req *http.Request, prvdr oauth.Provider, restrictedTokenID string, state string, errorCode string) (*auth.RestrictedToken, error) {
259261
if restrictedToken, err := r.AuthClient().GetRestrictedToken(req.Context(), restrictedTokenID); err != nil {
260262
return nil, err
261-
} else if restrictedToken != nil && restrictedToken.Authenticates(req) && (state == prvdr.CalculateStateForRestrictedToken(restrictedToken.ID) || errorCode == oauth.ErrorAccessDenied) {
263+
} else if restrictedToken != nil && restrictedToken.Authenticates(req) && (state == prvdr.CalculateStateForRestrictedToken(restrictedToken.ID) || prvdr.IsErrorCodeAccessDenied(errorCode)) {
262264
return restrictedToken, nil
263265
} else {
264266
return nil, nil

auth/service/api/v1/provider_session.go

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ import (
1616

1717
func (r *Router) ProviderSessionsRoutes() []*rest.Route {
1818
return []*rest.Route{
19-
rest.Get("/v1/users/:userId/provider_sessions", serviceApi.RequireServer(r.ListUserProviderSessions)),
2019
rest.Post("/v1/users/:userId/provider_sessions", serviceApi.RequireServer(r.CreateUserProviderSession)),
2120
rest.Delete("/v1/users/:userId/provider_sessions", serviceApi.RequireServer(r.DeleteUserProviderSessions)),
21+
rest.Get("/v1/provider_sessions", serviceApi.RequireServer(r.ListProviderSessions)),
2222
rest.Get("/v1/provider_sessions/:id", serviceApi.RequireServer(r.GetProviderSession)),
2323
rest.Put("/v1/provider_sessions/:id", serviceApi.RequireServer(r.UpdateProviderSession)),
2424
rest.Delete("/v1/provider_sessions/:id", serviceApi.RequireServer(r.DeleteProviderSession)),
@@ -28,7 +28,7 @@ func (r *Router) ProviderSessionsRoutes() []*rest.Route {
2828
}
2929
}
3030

31-
func (r *Router) ListUserProviderSessions(res rest.ResponseWriter, req *rest.Request) {
31+
func (r *Router) CreateUserProviderSession(res rest.ResponseWriter, req *rest.Request) {
3232
responder := request.MustNewResponder(res, req)
3333

3434
userID := req.PathParam("userId")
@@ -37,23 +37,22 @@ func (r *Router) ListUserProviderSessions(res rest.ResponseWriter, req *rest.Req
3737
return
3838
}
3939

40-
filter := auth.NewProviderSessionFilter()
41-
pagination := page.NewPagination()
42-
if err := request.DecodeRequestQuery(req.Request, filter, pagination); err != nil {
40+
create := auth.NewProviderSessionCreate()
41+
if err := request.DecodeRequestBody(req.Request, create); err != nil {
4342
responder.Error(http.StatusBadRequest, err)
4443
return
4544
}
4645

47-
providerSessions, err := r.AuthClient().ListUserProviderSessions(req.Context(), userID, filter, pagination)
46+
providerSession, err := r.AuthClient().CreateUserProviderSession(req.Context(), userID, create)
4847
if err != nil {
4948
responder.Error(http.StatusInternalServerError, err)
5049
return
5150
}
5251

53-
responder.Data(http.StatusOK, providerSessions)
52+
responder.Data(http.StatusCreated, providerSession)
5453
}
5554

56-
func (r *Router) CreateUserProviderSession(res rest.ResponseWriter, req *rest.Request) {
55+
func (r *Router) DeleteUserProviderSessions(res rest.ResponseWriter, req *rest.Request) {
5756
responder := request.MustNewResponder(res, req)
5857

5958
userID := req.PathParam("userId")
@@ -62,36 +61,31 @@ func (r *Router) CreateUserProviderSession(res rest.ResponseWriter, req *rest.Re
6261
return
6362
}
6463

65-
create := auth.NewProviderSessionCreate()
66-
if err := request.DecodeRequestBody(req.Request, create); err != nil {
67-
responder.Error(http.StatusBadRequest, err)
68-
return
69-
}
70-
71-
providerSession, err := r.AuthClient().CreateUserProviderSession(req.Context(), userID, create)
72-
if err != nil {
64+
if err := r.AuthClient().DeleteUserProviderSessions(req.Context(), userID); err != nil {
7365
responder.Error(http.StatusInternalServerError, err)
7466
return
7567
}
7668

77-
responder.Data(http.StatusCreated, providerSession)
69+
responder.Empty(http.StatusNoContent)
7870
}
7971

80-
func (r *Router) DeleteUserProviderSessions(res rest.ResponseWriter, req *rest.Request) {
72+
func (r *Router) ListProviderSessions(res rest.ResponseWriter, req *rest.Request) {
8173
responder := request.MustNewResponder(res, req)
8274

83-
userID := req.PathParam("userId")
84-
if userID == "" {
85-
responder.Error(http.StatusBadRequest, request.ErrorParameterMissing("userId"))
75+
filter := auth.NewProviderSessionFilter()
76+
pagination := page.NewPagination()
77+
if err := request.DecodeRequestQuery(req.Request, filter, pagination); err != nil {
78+
responder.Error(http.StatusBadRequest, err)
8679
return
8780
}
8881

89-
if err := r.AuthClient().DeleteUserProviderSessions(req.Context(), userID); err != nil {
82+
providerSessions, err := r.AuthClient().ListProviderSessions(req.Context(), filter, pagination)
83+
if err != nil {
9084
responder.Error(http.StatusInternalServerError, err)
9185
return
9286
}
9387

94-
responder.Empty(http.StatusNoContent)
88+
responder.Data(http.StatusOK, providerSessions)
9589
}
9690

9791
func (r *Router) GetProviderSession(res rest.ResponseWriter, req *rest.Request) {

auth/service/service/client.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/tidepool-org/platform/log"
1111
"github.com/tidepool-org/platform/page"
1212
"github.com/tidepool-org/platform/platform"
13+
"github.com/tidepool-org/platform/pointer"
1314
"github.com/tidepool-org/platform/provider"
1415
structureValidator "github.com/tidepool-org/platform/structure/validator"
1516
)
@@ -53,11 +54,6 @@ func NewClient(cfg *authClient.ExternalConfig, authorizeAs platform.AuthorizeAs,
5354
}, nil
5455
}
5556

56-
func (c *Client) ListUserProviderSessions(ctx context.Context, userID string, filter *auth.ProviderSessionFilter, pagination *page.Pagination) (auth.ProviderSessions, error) {
57-
repository := c.authStore.NewProviderSessionRepository()
58-
return repository.ListUserProviderSessions(ctx, userID, filter, pagination)
59-
}
60-
6157
func (c *Client) CreateUserProviderSession(ctx context.Context, userID string, create *auth.ProviderSessionCreate) (*auth.ProviderSession, error) {
6258
prvdr, err := c.providerFactory.Get(create.Type, create.Name)
6359
if err != nil {
@@ -97,7 +93,10 @@ func (c *Client) DeleteUserProviderSessions(ctx context.Context, userID string)
9793
repository := c.authStore.NewProviderSessionRepository()
9894

9995
// TODO: Add pagination if/when we ever get over one page of provider sessions
100-
if providerSessions, err := repository.ListUserProviderSessions(ctx, userID, nil, nil); err != nil {
96+
filter := &auth.ProviderSessionFilter{
97+
UserID: pointer.FromString(userID),
98+
}
99+
if providerSessions, err := repository.ListProviderSessions(ctx, filter, nil); err != nil {
101100
logger.WithError(err).Warn("Unable to list user provider sessions")
102101
} else {
103102
for _, providerSession := range providerSessions {
@@ -153,6 +152,11 @@ func (c *Client) DeleteAllProviderSessions(ctx context.Context, filter auth.Prov
153152
return nil
154153
}
155154

155+
func (c *Client) ListProviderSessions(ctx context.Context, filter *auth.ProviderSessionFilter, pagination *page.Pagination) (auth.ProviderSessions, error) {
156+
repository := c.authStore.NewProviderSessionRepository()
157+
return repository.ListProviderSessions(ctx, filter, pagination)
158+
}
159+
156160
func (c *Client) GetProviderSession(ctx context.Context, id string) (*auth.ProviderSession, error) {
157161
repository := c.authStore.NewProviderSessionRepository()
158162
return repository.GetProviderSession(ctx, id)

0 commit comments

Comments
 (0)