Skip to content

Commit

Permalink
feat(grant): update grant expiration date (#171)
Browse files Browse the repository at this point in the history
* feat(grant): update grant expiration date

* chore: fix lint

* fix: fix double imports

* fix: introduce Patch in grant repository to update falsy value to db

* feat: introduce grant diff in update

* fix: pass auth user as actor from handler

* fix: assign actors for diff items

* chore: remove is_permanent field from grant update payload

* fix: add check if grant is inactive

* fix: check update payload diff

* chore: handle error codes properly

* Revert "fix: check update payload diff"

This reverts commit 2dab9f5.

* test: fix test
  • Loading branch information
rahmatrhd authored Sep 4, 2024
1 parent 4a0c3b0 commit 50feb29
Show file tree
Hide file tree
Showing 18 changed files with 1,696 additions and 1,267 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ COMMIT := $(shell git rev-parse --short HEAD)
TAG := "$(shell git rev-list --tags --max-count=1)"
VERSION := "$(shell git describe --tags ${TAG})-next"
BUILD_DIR=dist
PROTON_COMMIT := "293abecafe5eda9ea683ced75644ded070134b2f"
PROTON_COMMIT := "3e2516714cd9d1ae239fba1ce70c2b9a9f754240"

.PHONY: all build clean test tidy vet proto setup format generate

Expand Down
21 changes: 21 additions & 0 deletions api/handler/v1beta1/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,27 @@ func (a *adapter) ToGrantProto(grant *domain.Grant) (*guardianv1beta1.Grant, err
return grantProto, nil
}

func (a *adapter) FromUpdateGrantRequestProto(grantUpdate *guardianv1beta1.UpdateGrantRequest) *domain.GrantUpdate {
if grantUpdate == nil {
return nil
}

gu := &domain.GrantUpdate{
ID: grantUpdate.GetId(),
ExpirationDateReason: grantUpdate.ExpirationDateReason,
}
if grantUpdate.GetOwner() != "" {
gu.Owner = &grantUpdate.Owner
}

if grantUpdate.ExpirationDate != nil {
expDate := grantUpdate.GetExpirationDate().AsTime()
gu.ExpirationDate = &expDate
}

return gu
}

func (a *adapter) ToActivityProto(activity *domain.Activity) (*guardianv1beta1.ProviderActivity, error) {
if activity == nil {
return nil, nil
Expand Down
17 changes: 11 additions & 6 deletions api/handler/v1beta1/grant.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,22 +120,27 @@ func (s *GRPCServer) RevokeGrant(ctx context.Context, req *guardianv1beta1.Revok
}

func (s *GRPCServer) UpdateGrant(ctx context.Context, req *guardianv1beta1.UpdateGrantRequest) (*guardianv1beta1.UpdateGrantResponse, error) {
g := &domain.Grant{
ID: req.GetId(),
Owner: req.GetOwner(),
actor, err := s.getUser(ctx)
if err != nil {
return nil, status.Error(codes.Unauthenticated, "failed to get metadata: actor")
}
if err := s.grantService.Update(ctx, g); err != nil {

payload := s.adapter.FromUpdateGrantRequestProto(req)
payload.Actor = actor
updatedGrant, err := s.grantService.Update(ctx, payload)
if err != nil {
switch {
case errors.Is(err, grant.ErrGrantNotFound):
return nil, status.Error(codes.NotFound, err.Error())
case errors.Is(err, grant.ErrEmptyOwner):
case errors.Is(err, grant.ErrEmptyOwner),
errors.Is(err, domain.ErrInvalidGrantUpdateRequest):
return nil, status.Error(codes.InvalidArgument, err.Error())
default:
return nil, s.internalError(ctx, "failed to update grant: %v", err)
}
}

grantProto, err := s.adapter.ToGrantProto(g)
grantProto, err := s.adapter.ToGrantProto(updatedGrant)
if err != nil {
return nil, s.internalError(ctx, "failed to parse grant: %v", err)
}
Expand Down
34 changes: 21 additions & 13 deletions api/handler/v1beta1/grant_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,27 +318,33 @@ func (s *GrpcHandlersSuite) TestUpdateGrant() {
s.Run("should return grant details on succes", func() {
s.setup()

expectedGrant := &domain.Grant{
actor := "actor@example.com"
newOwner := "test-owner"
expectedPayload := &domain.GrantUpdate{
ID: "test-id",
Owner: "test-owner",
Owner: &newOwner,
Actor: actor,
}
now := time.Now()
expectedLatestGrant := &domain.Grant{
ID: "test-id",
Owner: newOwner,
UpdatedAt: now,
}
s.grantService.EXPECT().
Update(mock.MatchedBy(func(ctx context.Context) bool { return true }), expectedGrant).
Run(func(_a0 context.Context, g *domain.Grant) {
g.UpdatedAt = now
}).
Return(nil).Once()
Update(mock.MatchedBy(func(ctx context.Context) bool { return true }), expectedPayload).
Return(expectedLatestGrant, nil).Once()

req := &guardianv1beta1.UpdateGrantRequest{
Id: "test-id",
Owner: "test-owner",
}
res, err := s.grpcServer.UpdateGrant(context.Background(), req)
ctx := context.WithValue(context.Background(), authEmailTestContextKey{}, actor)
res, err := s.grpcServer.UpdateGrant(ctx, req)

s.NoError(err)
s.Equal(expectedGrant.ID, res.Grant.Id)
s.Equal(expectedGrant.Owner, res.Grant.Owner)
s.Equal(expectedLatestGrant.ID, res.Grant.Id)
s.Equal(expectedLatestGrant.Owner, res.Grant.Owner)
s.Equal(timestamppb.New(now), res.Grant.UpdatedAt)
})

Expand Down Expand Up @@ -370,14 +376,16 @@ func (s *GrpcHandlersSuite) TestUpdateGrant() {
s.setup()

s.grantService.EXPECT().
Update(mock.MatchedBy(func(ctx context.Context) bool { return true }), mock.AnythingOfType("*domain.Grant")).
Return(tc.expectedError).Once()
Update(mock.MatchedBy(func(ctx context.Context) bool { return true }), mock.AnythingOfType("*domain.GrantUpdate")).
Return(nil, tc.expectedError).Once()

actor := "actor@example.com"
req := &guardianv1beta1.UpdateGrantRequest{
Id: "test-id",
Owner: "test-owner",
}
res, err := s.grpcServer.UpdateGrant(context.Background(), req)
ctx := context.WithValue(context.Background(), authEmailTestContextKey{}, actor)
res, err := s.grpcServer.UpdateGrant(ctx, req)

s.Equal(tc.expectedCode, status.Code(err))
s.Nil(res)
Expand Down
4 changes: 3 additions & 1 deletion api/handler/v1beta1/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ type ProtoAdapter interface {

ToGrantProto(*domain.Grant) (*guardianv1beta1.Grant, error)
FromGrantProto(*guardianv1beta1.Grant) *domain.Grant
FromUpdateGrantRequestProto(*guardianv1beta1.UpdateGrantRequest) *domain.GrantUpdate

ToActivityProto(*domain.Activity) (*guardianv1beta1.ProviderActivity, error)

ToCommentProto(*domain.Comment) *guardianv1beta1.AppealComment
ToAppealActivityProto(e *domain.Event) (*guardianv1beta1.AppealActivity, error)
// TODO: remove interface
}

//go:generate mockery --name=resourceService --exported --with-expecter
Expand Down Expand Up @@ -118,7 +120,7 @@ type grantService interface {
GetGrantsTotalCount(context.Context, domain.ListGrantsFilter) (int64, error)
List(context.Context, domain.ListGrantsFilter) ([]domain.Grant, error)
GetByID(context.Context, string) (*domain.Grant, error)
Update(context.Context, *domain.Grant) error
Update(context.Context, *domain.GrantUpdate) (*domain.Grant, error)
Restore(ctx context.Context, id, actor, reason string) (*domain.Grant, error)
Revoke(ctx context.Context, id, actor, reason string, opts ...grant.Option) (*domain.Grant, error)
BulkRevoke(ctx context.Context, filter domain.RevokeGrantsFilter, actor, reason string) ([]*domain.Grant, error)
Expand Down
34 changes: 23 additions & 11 deletions api/handler/v1beta1/mocks/grantService.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 50feb29

Please sign in to comment.