Skip to content

Commit

Permalink
feat: update last use time when api token is used (#210)
Browse files Browse the repository at this point in the history
Because

- we want users to be able to target the tokens that can be deprecated.

This commit

- Update token data when the token is used.
  • Loading branch information
chuang8511 authored Jun 4, 2024
1 parent 319c188 commit 10fa9e2
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 4 deletions.
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ toolchain go1.21.5
retract v0.3.2 // Published accidentally.

require (
github.com/DATA-DOG/go-sqlmock v1.5.2
github.com/InfluxCommunity/influxdb3-go v0.1.0
github.com/frankban/quicktest v1.14.6
github.com/gabriel-vasile/mimetype v1.4.3
Expand All @@ -17,7 +18,7 @@ require (
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1
github.com/iancoleman/strcase v0.2.0
github.com/influxdata/influxdb-client-go/v2 v2.12.3
github.com/instill-ai/protogen-go v0.3.3-alpha.0.20240423064822-66cd105bb99c
github.com/instill-ai/protogen-go v0.3.3-alpha.0.20240604160543-3126f88c532e
github.com/instill-ai/usage-client v0.2.4-alpha.0.20240123081026-6c78d9a5197a
github.com/instill-ai/x v0.4.0-alpha
github.com/knadh/koanf v1.5.0
Expand Down
7 changes: 5 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,8 @@ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBp
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/ClickHouse/clickhouse-go v1.4.3/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU=
github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU=
github.com/InfluxCommunity/influxdb3-go v0.1.0 h1:c+5H7qD7WZ0KSTCtCrVjBoMEspIP8KBO5LfVfLAaXn8=
github.com/InfluxCommunity/influxdb3-go v0.1.0/go.mod h1:6hVZLGqLyfEvXu14JRm4Ai938q8BzJ73TGQ7VKh8qPA=
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c h1:RGWPOewvKIROun94nF7v2cua9qP+thov/7M50KEoeSU=
Expand Down Expand Up @@ -1113,8 +1115,8 @@ github.com/influxdata/line-protocol/v2 v2.0.0-20210312151457-c52fdecb625a/go.mod
github.com/influxdata/line-protocol/v2 v2.1.0/go.mod h1:QKw43hdUBg3GTk2iC3iyCxksNj7PX9aUSeYOYE/ceHY=
github.com/influxdata/line-protocol/v2 v2.2.1 h1:EAPkqJ9Km4uAxtMRgUubJyqAr6zgWM0dznKMLRauQRE=
github.com/influxdata/line-protocol/v2 v2.2.1/go.mod h1:DmB3Cnh+3oxmG6LOBIxce4oaL4CPj3OmMPgvauXh+tM=
github.com/instill-ai/protogen-go v0.3.3-alpha.0.20240423064822-66cd105bb99c h1:mkaU0knUzNeyc4n94CYQPSZL81PCgYWeMThAlnoB6ew=
github.com/instill-ai/protogen-go v0.3.3-alpha.0.20240423064822-66cd105bb99c/go.mod h1:2blmpUwiTwxIDnrjIqT6FhR5ewshZZF554wzjXFvKpQ=
github.com/instill-ai/protogen-go v0.3.3-alpha.0.20240604160543-3126f88c532e h1:ihMq6jTeVHxE3E+pvpp2/Xo9Oh0TXpeJ69FsLB6znqc=
github.com/instill-ai/protogen-go v0.3.3-alpha.0.20240604160543-3126f88c532e/go.mod h1:2blmpUwiTwxIDnrjIqT6FhR5ewshZZF554wzjXFvKpQ=
github.com/instill-ai/usage-client v0.2.4-alpha.0.20240123081026-6c78d9a5197a h1:gmy8BcCFDZQan40c/D3f62DwTYtlCwi0VrSax+pKffw=
github.com/instill-ai/usage-client v0.2.4-alpha.0.20240123081026-6c78d9a5197a/go.mod h1:EpX3Yr661uWULtZf5UnJHfr5rw2PDyX8ku4Kx0UtYFw=
github.com/instill-ai/x v0.4.0-alpha h1:zQV2VLbSHjMv6gyBN/2mwwrvWk0/mJM6ZKS12AzjfQg=
Expand Down Expand Up @@ -1218,6 +1220,7 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE=
github.com/klauspost/asmfmt v1.3.2 h1:4Ri7ox3EwapiOjCki+hw14RyKk201CN4rzyCJRFLpK4=
github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE=
github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
Expand Down
9 changes: 8 additions & 1 deletion pkg/handler/publichandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -722,7 +722,7 @@ func (h *PublicHandler) CreateToken(ctx context.Context, req *mgmtPB.CreateToken
return resp, nil
}

// ListTokens lists all the API tokens of the authenticated user. This endpoint is not supported yet.
// ListTokens lists all the API tokens of the authenticated user.
func (h *PublicHandler) ListTokens(ctx context.Context, req *mgmtPB.ListTokensRequest) (*mgmtPB.ListTokensResponse, error) {

eventName := "ListTokens"
Expand Down Expand Up @@ -864,6 +864,13 @@ func (h *PublicHandler) ValidateToken(ctx context.Context, req *mgmtPB.ValidateT
return nil, err
}

err = h.Service.UpdateTokenLastUseTime(ctx, apiToken)

if err != nil {
span.SetStatus(1, err.Error())
return nil, err
}

return &mgmtPB.ValidateTokenResponse{UserUid: userUID}, nil
}

Expand Down
1 change: 1 addition & 0 deletions pkg/repository/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ import "errors"
var ErrPageTokenDecode = errors.New("page token decode error")
var ErrOwnerTypeNotMatch = errors.New("owner type not match")
var ErrNoDataDeleted = errors.New("no data deleted")
var ErrNoDataUpdated = errors.New("no data updated")
20 changes: 20 additions & 0 deletions pkg/repository/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ type Repository interface {
GetToken(ctx context.Context, owner string, id string) (*datamodel.Token, error)
DeleteToken(ctx context.Context, owner string, id string) error
LookupToken(ctx context.Context, token string) (*datamodel.Token, error)
UpdateTokenLastUseTime(ctx context.Context, accessToken string) error

ListAllValidTokens(ctx context.Context) ([]datamodel.Token, error)
}
Expand Down Expand Up @@ -471,3 +472,22 @@ func (r *repository) DeleteToken(ctx context.Context, owner string, id string) e

return nil
}

func (r *repository) UpdateTokenLastUseTime(ctx context.Context, accessToken string) error {
r.PinUser(ctx)
db := r.CheckPinnedUser(ctx, r.db)

result := db.Model(&datamodel.Token{}).
Where("access_token = ?", accessToken).
Update("last_use_time", time.Now())

if result.Error != nil {
return result.Error
}

if result.RowsAffected == 0 {
return ErrNoDataUpdated
}

return nil
}
53 changes: 53 additions & 0 deletions pkg/repository/repository_mocksql_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package repository

import (
"context"
"database/sql"
"regexp"
"testing"

"github.com/DATA-DOG/go-sqlmock"
qt "github.com/frankban/quicktest"
"github.com/go-redis/redismock/v9"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)

func mockDBRepository() (sqlmock.Sqlmock, *sql.DB, Repository, error) {
sqldb, mock, err := sqlmock.New()
if err != nil {
return nil, nil, nil, err
}

gormdb, err := gorm.Open(postgres.New(postgres.Config{
Conn: sqldb,
}))

if err != nil {
return nil, nil, nil, err
}

redisClient, _ := redismock.NewClientMock()
repository := NewRepository(gormdb, redisClient)

return mock, sqldb, repository, err
}

func TestRepository_UpdateTokenLastUseTime(t *testing.T) {
c := qt.New(t)
tokenAccess := "fakeTokenAccess"

mock, sqldb, repository, err := mockDBRepository()
c.Assert(err, qt.IsNil)
defer sqldb.Close()

mock.ExpectBegin()
mock.ExpectExec(regexp.QuoteMeta(`UPDATE "tokens" SET "last_use_time"=$1,"update_time"=$2 WHERE access_token = $3`)).
WithArgs(sqlmock.AnyArg(), sqlmock.AnyArg(), tokenAccess).
WillReturnResult(sqlmock.NewResult(1, 1))

mock.ExpectCommit()

err = repository.UpdateTokenLastUseTime(context.Background(), tokenAccess)
c.Assert(err, qt.IsNil)
}
1 change: 1 addition & 0 deletions pkg/service/convertor.go
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ func (s *service) DBToken2PBToken(ctx context.Context, dbToken *datamodel.Token)
Expiration: &mgmtPB.ApiToken_ExpireTime{ExpireTime: timestamppb.New(dbToken.ExpireTime)},
CreateTime: timestamppb.New(dbToken.Base.CreateTime),
UpdateTime: timestamppb.New(dbToken.Base.UpdateTime),
LastUseTime: timestamppb.New(dbToken.LastUseTime),
}, nil
}

Expand Down
6 changes: 6 additions & 0 deletions pkg/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ type Service interface {
GetToken(ctx context.Context, ctxUserUID uuid.UUID, id string) (*mgmtPB.ApiToken, error)
DeleteToken(ctx context.Context, ctxUserUID uuid.UUID, id string) error
ValidateToken(ctx context.Context, accessToken string) (string, error)
UpdateTokenLastUseTime(ctx context.Context, accessToken string) error

CheckUserPassword(ctx context.Context, uid uuid.UUID, password string) error
UpdateUserPassword(ctx context.Context, uid uuid.UUID, newPassword string) error
Expand Down Expand Up @@ -648,6 +649,11 @@ func (s *service) DeleteToken(ctx context.Context, ctxUserUID uuid.UUID, id stri
}
return nil
}

func (s *service) UpdateTokenLastUseTime(ctx context.Context, accessToken string) error {
return s.repository.UpdateTokenLastUseTime(ctx, accessToken)
}

func (s *service) ValidateToken(ctx context.Context, accessToken string) (string, error) {
uid := s.getAPITokenFromCache(ctx, accessToken)
if uid == uuid.Nil {
Expand Down

0 comments on commit 10fa9e2

Please sign in to comment.