Skip to content

Commit a94e44e

Browse files
author
Laurie T. Malau
committed
[pat] Implement GetPersonalAccessToken
1 parent 2d211fe commit a94e44e

File tree

6 files changed

+104
-33
lines changed

6 files changed

+104
-33
lines changed

components/gitpod-db/go/go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ require (
1919
)
2020

2121
require (
22+
github.com/bufbuild/connect-go v1.1.0 // indirect
2223
github.com/davecgh/go-spew v1.1.1 // indirect
2324
github.com/golang/protobuf v1.5.2 // indirect
2425
github.com/jinzhu/inflection v1.0.0 // indirect

components/gitpod-db/go/go.sum

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

components/gitpod-db/go/personal_access_token.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,17 @@ func (d *PersonalAccessToken) TableName() string {
3636
return "d_b_personal_access_token"
3737
}
3838

39-
func GetToken(ctx context.Context, conn *gorm.DB, id uuid.UUID) (PersonalAccessToken, error) {
39+
func GetPersonalAccessTokenForUser(ctx context.Context, conn *gorm.DB, tokenID uuid.UUID, userID uuid.UUID) (PersonalAccessToken, error) {
4040
var token PersonalAccessToken
4141

4242
db := conn.WithContext(ctx)
4343

44-
db = db.Where("id = ?", id).First(&token)
44+
db = db.Where("id = ?", tokenID).Where("userId = ?", userID).Where("deleted = ?", 0).First(&token)
4545
if db.Error != nil {
46-
return PersonalAccessToken{}, fmt.Errorf("Failed to retrieve token: %w", db.Error)
46+
if errors.Is(db.Error, gorm.ErrRecordNotFound) {
47+
return PersonalAccessToken{}, fmt.Errorf("Token with ID %s does not exist: %w", tokenID, ErrorNotFound)
48+
}
49+
return PersonalAccessToken{}, fmt.Errorf("Failed to retrieve token: %v", db.Error)
4750
}
4851

4952
return token, nil
@@ -95,6 +98,7 @@ func ListPersonalAccessTokensForUser(ctx context.Context, conn *gorm.DB, userID
9598
WithContext(ctx).
9699
Table((&PersonalAccessToken{}).TableName()).
97100
Where("userId = ?", userID).
101+
Where("deleted = ?", 0).
98102
Order("createdAt").
99103
Scopes(Paginate(pagination)).
100104
Find(&results)

components/gitpod-db/go/personal_access_token_test.go

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,38 @@ import (
1919
func TestPersonalAccessToken_Get(t *testing.T) {
2020
conn := dbtest.ConnectForTests(t)
2121

22-
token := db.PersonalAccessToken{
23-
ID: uuid.New(),
24-
UserID: uuid.New(),
25-
Hash: "some-secure-hash",
26-
Name: "some-name",
27-
Description: "some-description",
28-
Scopes: []string{"read", "write"},
29-
ExpirationTime: time.Now().Add(5),
30-
CreatedAt: time.Now(),
31-
LastModified: time.Now(),
32-
}
22+
firstUserId := uuid.New()
23+
secondUserId := uuid.New()
3324

34-
tx := conn.Create(token)
35-
require.NoError(t, tx.Error)
25+
token := dbtest.NewPersonalAccessToken(t, db.PersonalAccessToken{UserID: firstUserId})
26+
token2 := dbtest.NewPersonalAccessToken(t, db.PersonalAccessToken{UserID: secondUserId})
27+
28+
tokenEntries := []db.PersonalAccessToken{token, token2}
29+
30+
dbtest.CreatePersonalAccessTokenRecords(t, conn, tokenEntries...)
31+
32+
t.Run("not matching user", func(t *testing.T) {
33+
_, err := db.GetPersonalAccessTokenForUser(context.Background(), conn, token.ID, token2.UserID)
34+
require.Error(t, err, db.ErrorNotFound)
35+
})
36+
37+
t.Run("not matching token", func(t *testing.T) {
38+
_, err := db.GetPersonalAccessTokenForUser(context.Background(), conn, token2.ID, token.UserID)
39+
require.Error(t, err, db.ErrorNotFound)
40+
})
41+
42+
t.Run("both token and user don't exist in the DB", func(t *testing.T) {
43+
_, err := db.GetPersonalAccessTokenForUser(context.Background(), conn, uuid.New(), uuid.New())
44+
require.Error(t, err, db.ErrorNotFound)
45+
})
46+
47+
t.Run("valid", func(t *testing.T) {
48+
returned, err := db.GetPersonalAccessTokenForUser(context.Background(), conn, token.ID, token.UserID)
49+
require.NoError(t, err)
50+
require.Equal(t, token.ID, returned.ID)
51+
require.Equal(t, token.UserID, returned.UserID)
52+
})
3653

37-
result, err := db.GetToken(context.Background(), conn, token.ID)
38-
require.NoError(t, err)
39-
require.Equal(t, token.ID, result.ID)
4054
}
4155

4256
func TestPersonalAccessToken_Create(t *testing.T) {

components/public-api-server/pkg/apiv1/tokens.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
"fmt"
1111
"strings"
1212

13-
"github.com/bufbuild/connect-go"
13+
connect "github.com/bufbuild/connect-go"
1414
"github.com/gitpod-io/gitpod/common-go/experiments"
1515
"github.com/gitpod-io/gitpod/common-go/log"
1616
db "github.com/gitpod-io/gitpod/components/gitpod-db/go"
@@ -113,13 +113,22 @@ func (s *TokensService) GetPersonalAccessToken(ctx context.Context, req *connect
113113
return nil, err
114114
}
115115

116-
_, _, err = s.getUser(ctx, conn)
116+
_, userId, err := s.getUser(ctx, conn)
117117
if err != nil {
118+
if errors.Is(err, db.ErrorNotFound) {
119+
return nil, connect.NewError(connect.CodeNotFound, err)
120+
}
118121
return nil, err
119122
}
120123

121124
log.Infof("Handling GetPersonalAccessToken request for Token ID '%s'", tokenID.String())
122-
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("gitpod.experimental.v1.TokensService.GetPersonalAccessToken is not implemented"))
125+
126+
token, err := db.GetPersonalAccessTokenForUser(ctx, s.dbConn, tokenID, userId)
127+
if err != nil {
128+
return nil, err
129+
}
130+
131+
return connect.NewResponse(&v1.GetPersonalAccessTokenResponse{Token: personalAccessTokenToAPI(token, "")}), nil
123132
}
124133

125134
func (s *TokensService) ListPersonalAccessTokens(ctx context.Context, req *connect.Request[v1.ListPersonalAccessTokensRequest]) (*connect.Response[v1.ListPersonalAccessTokensResponse], error) {

components/public-api-server/pkg/apiv1/tokens_test.go

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package apiv1
66

77
import (
88
"context"
9+
"fmt"
910
"net/http"
1011
"net/http/httptest"
1112
"testing"
@@ -127,26 +128,39 @@ func TestTokensService_CreatePersonalAccessTokenWithoutFeatureFlag(t *testing.T)
127128
require.NoError(t, err)
128129

129130
// token must exist in the DB, with the User ID of the requestor
130-
storedInDB, err := db.GetToken(context.Background(), dbConn, uuid.MustParse(created.GetId()))
131+
storedInDB, err := db.GetPersonalAccessTokenForUser(context.Background(), dbConn, uuid.MustParse(created.GetId()), uuid.MustParse(user.ID))
131132
require.NoError(t, err)
132133
require.Equal(t, user.ID, storedInDB.UserID.String())
133134
})
134135
}
135136

136137
func TestTokensService_GetPersonalAccessToken(t *testing.T) {
137138
user := newUser(&protocol.User{})
139+
user2 := newUser(&protocol.User{})
138140

139-
t.Run("permission denied when feature flag is disabled", func(t *testing.T) {
140-
serverMock, _, client := setupTokensService(t, withTokenFeatureDisabled)
141+
t.Run("get correct token", func(t *testing.T) {
142+
serverMock, dbConn, client := setupTokensService(t, withTokenFeatureEnabled)
143+
144+
tokens := dbtest.CreatePersonalAccessTokenRecords(t, dbConn,
145+
dbtest.NewPersonalAccessToken(t, db.PersonalAccessToken{
146+
UserID: uuid.MustParse(user.ID),
147+
}),
148+
dbtest.NewPersonalAccessToken(t, db.PersonalAccessToken{
149+
UserID: uuid.MustParse(user2.ID),
150+
}),
151+
)
141152

142153
serverMock.EXPECT().GetLoggedInUser(gomock.Any()).Return(user, nil)
143154

144-
_, err := client.GetPersonalAccessToken(context.Background(), connect.NewRequest(&v1.GetPersonalAccessTokenRequest{
145-
Id: uuid.New().String(),
155+
response, err := client.GetPersonalAccessToken(context.Background(), connect.NewRequest(&v1.GetPersonalAccessTokenRequest{
156+
Id: tokens[0].ID.String(),
146157
}))
147158

148-
require.Error(t, err, "This feature is currently in beta. If you would like to be part of the beta, please contact us.")
149-
require.Equal(t, connect.CodePermissionDenied, connect.CodeOf(err))
159+
require.NoError(t, err)
160+
161+
requireEqualProto(t, &v1.GetPersonalAccessTokenResponse{
162+
Token: personalAccessTokenToAPI(tokens[0], ""),
163+
}, response.Msg)
150164
})
151165

152166
t.Run("invalid argument when Token ID is empty", func(t *testing.T) {
@@ -167,16 +181,43 @@ func TestTokensService_GetPersonalAccessToken(t *testing.T) {
167181
require.Equal(t, connect.CodeInvalidArgument, connect.CodeOf(err))
168182
})
169183

170-
t.Run("unimplemented when feature flag enabled", func(t *testing.T) {
171-
serverMock, _, client := setupTokensService(t, withTokenFeatureEnabled)
184+
t.Run("responds with not found when token is not found", func(t *testing.T) {
185+
serverMock, dbConn, client := setupTokensService(t, withTokenFeatureEnabled)
186+
187+
someTokenId := uuid.New().String()
188+
189+
dbtest.CreatePersonalAccessTokenRecords(t, dbConn,
190+
dbtest.NewPersonalAccessToken(t, db.PersonalAccessToken{
191+
UserID: uuid.MustParse(user.ID),
192+
}),
193+
)
172194

173195
serverMock.EXPECT().GetLoggedInUser(gomock.Any()).Return(user, nil)
174196

175197
_, err := client.GetPersonalAccessToken(context.Background(), connect.NewRequest(&v1.GetPersonalAccessTokenRequest{
176-
Id: uuid.New().String(),
198+
Id: someTokenId,
177199
}))
178200

179-
require.Equal(t, connect.CodeUnimplemented, connect.CodeOf(err))
201+
require.Error(t, err, fmt.Errorf("Token with ID %s does not exist: not found", someTokenId))
202+
})
203+
204+
t.Run("permission denied when feature flag disabled", func(t *testing.T) {
205+
serverMock, dbConn, client := setupTokensService(t, withTokenFeatureDisabled)
206+
207+
tokens := dbtest.CreatePersonalAccessTokenRecords(t, dbConn,
208+
dbtest.NewPersonalAccessToken(t, db.PersonalAccessToken{
209+
UserID: uuid.MustParse(user.ID),
210+
}),
211+
)
212+
213+
serverMock.EXPECT().GetLoggedInUser(gomock.Any()).Return(user, nil)
214+
215+
_, err := client.GetPersonalAccessToken(context.Background(), connect.NewRequest(&v1.GetPersonalAccessTokenRequest{
216+
Id: tokens[0].ID.String(),
217+
}))
218+
219+
require.Error(t, err, "This feature is currently in beta. If you would like to be part of the beta, please contact us.")
220+
require.Equal(t, connect.CodePermissionDenied, connect.CodeOf(err))
180221
})
181222
}
182223

0 commit comments

Comments
 (0)