mirror of
https://github.com/gitpod-io/gitpod.git
synced 2025-12-08 17:36:30 +00:00
356 lines
11 KiB
Go
356 lines
11 KiB
Go
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
|
|
// Licensed under the GNU Affero General Public License (AGPL).
|
|
// See License.AGPL.txt in the project root for license information.
|
|
|
|
package db_test
|
|
|
|
import (
|
|
"context"
|
|
"strconv"
|
|
"testing"
|
|
"time"
|
|
|
|
db "github.com/gitpod-io/gitpod/components/gitpod-db/go"
|
|
"github.com/gitpod-io/gitpod/components/gitpod-db/go/dbtest"
|
|
"github.com/google/uuid"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestPersonalAccessToken_Get(t *testing.T) {
|
|
conn := dbtest.ConnectForTests(t)
|
|
|
|
firstUserId := uuid.New()
|
|
secondUserId := uuid.New()
|
|
|
|
token := dbtest.NewPersonalAccessToken(t, db.PersonalAccessToken{UserID: firstUserId})
|
|
token2 := dbtest.NewPersonalAccessToken(t, db.PersonalAccessToken{UserID: secondUserId})
|
|
|
|
tokenEntries := []db.PersonalAccessToken{token, token2}
|
|
|
|
dbtest.CreatePersonalAccessTokenRecords(t, conn, tokenEntries...)
|
|
|
|
t.Run("nil token ID is rejected", func(t *testing.T) {
|
|
_, err := db.GetPersonalAccessTokenForUser(context.Background(), conn, uuid.Nil, token.UserID)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("nil user ID is rejected", func(t *testing.T) {
|
|
_, err := db.GetPersonalAccessTokenForUser(context.Background(), conn, token.ID, uuid.Nil)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("not matching user", func(t *testing.T) {
|
|
_, err := db.GetPersonalAccessTokenForUser(context.Background(), conn, token.ID, token2.UserID)
|
|
require.Error(t, err, db.ErrorNotFound)
|
|
})
|
|
|
|
t.Run("not matching token", func(t *testing.T) {
|
|
_, err := db.GetPersonalAccessTokenForUser(context.Background(), conn, token2.ID, token.UserID)
|
|
require.Error(t, err, db.ErrorNotFound)
|
|
})
|
|
|
|
t.Run("both token and user don't exist in the DB", func(t *testing.T) {
|
|
_, err := db.GetPersonalAccessTokenForUser(context.Background(), conn, uuid.New(), uuid.New())
|
|
require.Error(t, err, db.ErrorNotFound)
|
|
})
|
|
|
|
t.Run("valid", func(t *testing.T) {
|
|
returned, err := db.GetPersonalAccessTokenForUser(context.Background(), conn, token.ID, token.UserID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, token.ID, returned.ID)
|
|
require.Equal(t, token.UserID, returned.UserID)
|
|
})
|
|
|
|
}
|
|
|
|
func TestPersonalAccessToken_Create(t *testing.T) {
|
|
conn := dbtest.ConnectForTests(t)
|
|
|
|
request := db.PersonalAccessToken{
|
|
ID: uuid.New(),
|
|
UserID: uuid.New(),
|
|
Hash: "another-secure-hash",
|
|
Name: "another-name",
|
|
Scopes: []string{"read", "write"},
|
|
ExpirationTime: time.Now().Add(5),
|
|
CreatedAt: time.Now(),
|
|
LastModified: time.Now(),
|
|
}
|
|
|
|
result, err := db.CreatePersonalAccessToken(context.Background(), conn, request)
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, request.ID, result.ID)
|
|
}
|
|
|
|
func TestPersonalAccessToken_UpdateHash(t *testing.T) {
|
|
conn := dbtest.ConnectForTests(t)
|
|
|
|
firstUserId := uuid.New()
|
|
secondUserId := uuid.New()
|
|
|
|
token := dbtest.NewPersonalAccessToken(t, db.PersonalAccessToken{UserID: firstUserId})
|
|
token2 := dbtest.NewPersonalAccessToken(t, db.PersonalAccessToken{UserID: secondUserId})
|
|
|
|
tokenEntries := []db.PersonalAccessToken{token, token2}
|
|
|
|
dbtest.CreatePersonalAccessTokenRecords(t, conn, tokenEntries...)
|
|
|
|
var newHash = "another-secure-hash"
|
|
var newExpirationTime = time.Now().Add(24 * time.Hour).UTC().Truncate(time.Millisecond)
|
|
|
|
t.Run("not matching user", func(t *testing.T) {
|
|
_, err := db.UpdatePersonalAccessTokenHash(context.Background(), conn, token.ID, token2.UserID, newHash, newExpirationTime)
|
|
require.Error(t, err, db.ErrorNotFound)
|
|
})
|
|
|
|
t.Run("not matching token", func(t *testing.T) {
|
|
_, err := db.UpdatePersonalAccessTokenHash(context.Background(), conn, token2.ID, token.UserID, newHash, newExpirationTime)
|
|
require.Error(t, err, db.ErrorNotFound)
|
|
})
|
|
|
|
t.Run("both token and user don't exist in the DB", func(t *testing.T) {
|
|
_, err := db.UpdatePersonalAccessTokenHash(context.Background(), conn, uuid.New(), uuid.New(), newHash, newExpirationTime)
|
|
require.Error(t, err, db.ErrorNotFound)
|
|
})
|
|
|
|
t.Run("valid", func(t *testing.T) {
|
|
returned, err := db.UpdatePersonalAccessTokenHash(context.Background(), conn, token.ID, token.UserID, newHash, newExpirationTime)
|
|
require.NoError(t, err)
|
|
require.Equal(t, token.ID, returned.ID)
|
|
require.Equal(t, token.UserID, returned.UserID)
|
|
require.Equal(t, newHash, returned.Hash)
|
|
require.Equal(t, token.Name, returned.Name)
|
|
require.Equal(t, token.Scopes, returned.Scopes)
|
|
require.Equal(t, newExpirationTime, returned.ExpirationTime)
|
|
require.Equal(t, token.CreatedAt, returned.CreatedAt)
|
|
})
|
|
}
|
|
|
|
func TestPersonalAccessToken_Delete(t *testing.T) {
|
|
conn := dbtest.ConnectForTests(t)
|
|
|
|
firstUserId := uuid.New()
|
|
secondUserId := uuid.New()
|
|
|
|
token := dbtest.NewPersonalAccessToken(t, db.PersonalAccessToken{UserID: firstUserId})
|
|
token2 := dbtest.NewPersonalAccessToken(t, db.PersonalAccessToken{UserID: secondUserId})
|
|
|
|
tokenEntries := []db.PersonalAccessToken{token, token2}
|
|
|
|
dbtest.CreatePersonalAccessTokenRecords(t, conn, tokenEntries...)
|
|
|
|
t.Run("not matching user", func(t *testing.T) {
|
|
count, err := db.DeletePersonalAccessTokenForUser(context.Background(), conn, token.ID, token2.UserID)
|
|
require.Error(t, err, db.ErrorNotFound)
|
|
require.Equal(t, int64(0), count)
|
|
})
|
|
|
|
t.Run("not matching token", func(t *testing.T) {
|
|
count, err := db.DeletePersonalAccessTokenForUser(context.Background(), conn, token2.ID, token.UserID)
|
|
require.Error(t, err, db.ErrorNotFound)
|
|
require.Equal(t, int64(0), count)
|
|
})
|
|
|
|
t.Run("both token and user don't exist in the DB", func(t *testing.T) {
|
|
count, err := db.DeletePersonalAccessTokenForUser(context.Background(), conn, uuid.New(), uuid.New())
|
|
require.Error(t, err, db.ErrorNotFound)
|
|
require.Equal(t, int64(0), count)
|
|
})
|
|
|
|
t.Run("valid", func(t *testing.T) {
|
|
count, err := db.DeletePersonalAccessTokenForUser(context.Background(), conn, token.ID, token.UserID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, int64(1), count)
|
|
_, err = db.GetPersonalAccessTokenForUser(context.Background(), conn, token.ID, token.UserID)
|
|
require.Error(t, err, db.ErrorNotFound)
|
|
})
|
|
}
|
|
|
|
func TestListPersonalAccessTokensForUser(t *testing.T) {
|
|
ctx := context.Background()
|
|
conn := dbtest.ConnectForTests(t)
|
|
pagination := db.Pagination{
|
|
Page: 1,
|
|
PageSize: 10,
|
|
}
|
|
|
|
userA := uuid.New()
|
|
userB := uuid.New()
|
|
|
|
now := time.Now().UTC()
|
|
|
|
dbtest.CreatePersonalAccessTokenRecords(t, conn,
|
|
dbtest.NewPersonalAccessToken(t, db.PersonalAccessToken{
|
|
UserID: userA,
|
|
CreatedAt: now.Add(-1 * time.Minute),
|
|
}),
|
|
dbtest.NewPersonalAccessToken(t, db.PersonalAccessToken{
|
|
UserID: userA,
|
|
CreatedAt: now,
|
|
}),
|
|
dbtest.NewPersonalAccessToken(t, db.PersonalAccessToken{
|
|
UserID: userB,
|
|
}),
|
|
)
|
|
|
|
tokensForUserA, err := db.ListPersonalAccessTokensForUser(ctx, conn, userA, pagination)
|
|
require.NoError(t, err)
|
|
require.Len(t, tokensForUserA.Results, 2)
|
|
|
|
tokensForUserB, err := db.ListPersonalAccessTokensForUser(ctx, conn, userB, pagination)
|
|
require.NoError(t, err)
|
|
require.Len(t, tokensForUserB.Results, 1)
|
|
|
|
tokensForUserWithNoData, err := db.ListPersonalAccessTokensForUser(ctx, conn, uuid.New(), pagination)
|
|
require.NoError(t, err)
|
|
require.Len(t, tokensForUserWithNoData.Results, 0)
|
|
}
|
|
|
|
func TestListPersonalAccessTokens_DeletedTokensAreNotListed(t *testing.T) {
|
|
conn := dbtest.ConnectForTests(t)
|
|
|
|
token := dbtest.CreatePersonalAccessTokenRecords(t, conn,
|
|
dbtest.NewPersonalAccessToken(t, db.PersonalAccessToken{}),
|
|
)[0]
|
|
|
|
_, err := db.DeletePersonalAccessTokenForUser(context.Background(), conn, token.ID, token.UserID)
|
|
require.NoError(t, err)
|
|
|
|
listed, err := db.ListPersonalAccessTokensForUser(context.Background(), conn, token.UserID, db.Pagination{
|
|
Page: 1,
|
|
PageSize: 10,
|
|
})
|
|
require.NoError(t, err)
|
|
require.Empty(t, listed.Results)
|
|
require.EqualValues(t, 0, listed.Total)
|
|
}
|
|
|
|
func TestListPersonalAccessTokensForUser_PaginateThroughResults(t *testing.T) {
|
|
ctx := context.Background()
|
|
conn := dbtest.ConnectForTests(t).Debug()
|
|
|
|
userA := uuid.New()
|
|
|
|
total := 11
|
|
var toCreate []db.PersonalAccessToken
|
|
for i := 0; i < total; i++ {
|
|
toCreate = append(toCreate, dbtest.NewPersonalAccessToken(t, db.PersonalAccessToken{
|
|
UserID: userA,
|
|
Name: strconv.Itoa(i),
|
|
}))
|
|
}
|
|
|
|
dbtest.CreatePersonalAccessTokenRecords(t, conn, toCreate...)
|
|
|
|
batch1, err := db.ListPersonalAccessTokensForUser(ctx, conn, userA, db.Pagination{
|
|
Page: 1,
|
|
PageSize: 5,
|
|
})
|
|
require.NoError(t, err)
|
|
require.Len(t, batch1.Results, 5)
|
|
require.EqualValues(t, batch1.Total, total)
|
|
|
|
batch2, err := db.ListPersonalAccessTokensForUser(ctx, conn, userA, db.Pagination{
|
|
Page: 2,
|
|
PageSize: 5,
|
|
})
|
|
require.NoError(t, err)
|
|
require.Len(t, batch2.Results, 5)
|
|
require.EqualValues(t, batch2.Total, total)
|
|
|
|
batch3, err := db.ListPersonalAccessTokensForUser(ctx, conn, userA, db.Pagination{
|
|
Page: 3,
|
|
PageSize: 5,
|
|
})
|
|
require.NoError(t, err)
|
|
require.Len(t, batch3.Results, 1)
|
|
require.EqualValues(t, batch3.Total, total)
|
|
}
|
|
|
|
func TestUpdatePersonalAccessTokenForUser(t *testing.T) {
|
|
|
|
newName := "second"
|
|
newScopes := db.Scopes([]string{})
|
|
|
|
t.Run("not found when record does not exist", func(t *testing.T) {
|
|
conn := dbtest.ConnectForTests(t)
|
|
|
|
_, err := db.UpdatePersonalAccessTokenForUser(context.Background(), conn, db.UpdatePersonalAccessTokenOpts{
|
|
TokenID: uuid.New(),
|
|
UserID: uuid.New(),
|
|
Name: &newName,
|
|
})
|
|
require.Error(t, err)
|
|
require.ErrorIs(t, err, db.ErrorNotFound)
|
|
})
|
|
|
|
t.Run("no modified field completes gracefully", func(t *testing.T) {
|
|
conn := dbtest.ConnectForTests(t)
|
|
name := "first"
|
|
|
|
created := dbtest.CreatePersonalAccessTokenRecords(t, conn, dbtest.NewPersonalAccessToken(t, db.PersonalAccessToken{
|
|
Name: name,
|
|
}))[0]
|
|
|
|
udpated, err := db.UpdatePersonalAccessTokenForUser(context.Background(), conn, db.UpdatePersonalAccessTokenOpts{
|
|
TokenID: created.ID,
|
|
UserID: created.UserID,
|
|
Name: &name,
|
|
})
|
|
require.NoError(t, err)
|
|
require.Equal(t, name, udpated.Name)
|
|
require.Len(t, udpated.Scopes, 0)
|
|
})
|
|
|
|
t.Run("no update when all options are nil", func(t *testing.T) {
|
|
conn := dbtest.ConnectForTests(t)
|
|
|
|
created := dbtest.CreatePersonalAccessTokenRecords(t, conn, dbtest.NewPersonalAccessToken(t, db.PersonalAccessToken{
|
|
Name: "first",
|
|
}))[0]
|
|
|
|
udpated, err := db.UpdatePersonalAccessTokenForUser(context.Background(), conn, db.UpdatePersonalAccessTokenOpts{
|
|
TokenID: created.ID,
|
|
UserID: created.UserID,
|
|
})
|
|
require.NoError(t, err)
|
|
require.Equal(t, created, udpated)
|
|
})
|
|
|
|
t.Run("updates name when it is not nil", func(t *testing.T) {
|
|
conn := dbtest.ConnectForTests(t)
|
|
|
|
created := dbtest.CreatePersonalAccessTokenRecords(t, conn, dbtest.NewPersonalAccessToken(t, db.PersonalAccessToken{
|
|
Name: "first",
|
|
}))[0]
|
|
|
|
udpated, err := db.UpdatePersonalAccessTokenForUser(context.Background(), conn, db.UpdatePersonalAccessTokenOpts{
|
|
TokenID: created.ID,
|
|
UserID: created.UserID,
|
|
Name: &newName,
|
|
})
|
|
require.NoError(t, err)
|
|
require.Equal(t, newName, udpated.Name)
|
|
require.Equal(t, created.Scopes, udpated.Scopes)
|
|
})
|
|
|
|
t.Run("updates scopes when it is not nil", func(t *testing.T) {
|
|
conn := dbtest.ConnectForTests(t)
|
|
|
|
created := dbtest.CreatePersonalAccessTokenRecords(t, conn, dbtest.NewPersonalAccessToken(t, db.PersonalAccessToken{
|
|
Name: "first",
|
|
Scopes: db.Scopes([]string{"foo"}),
|
|
}))[0]
|
|
|
|
udpated, err := db.UpdatePersonalAccessTokenForUser(context.Background(), conn, db.UpdatePersonalAccessTokenOpts{
|
|
TokenID: created.ID,
|
|
UserID: created.UserID,
|
|
Scopes: &newScopes,
|
|
})
|
|
require.NoError(t, err)
|
|
require.Equal(t, created.Name, udpated.Name)
|
|
require.Len(t, udpated.Scopes, len(newScopes))
|
|
})
|
|
}
|