Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(log,notifier): sending log and slack notif concurrently #144

Closed
wants to merge 40 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
8eacaff
feat: support appeal metadata to story metadata in policy details
Mar 22, 2024
a666fb5
fix: review fixes
Mar 22, 2024
49ce61e
chore: db migration for appeal_metadata_sources column
rahmatrhd Mar 25, 2024
f49140a
chore: generate proto
rahmatrhd Mar 25, 2024
9ef182c
chore: change AppealMetadataSource.Config type to interface{}; encryp…
rahmatrhd Mar 25, 2024
57f9853
fix: fix err == nil
rahmatrhd Mar 25, 2024
55363b4
fix: squash mapstructure embedded struct
rahmatrhd Mar 25, 2024
c59604d
feat: evaluate url if contains "$appeal" string
rahmatrhd Mar 25, 2024
a92cef3
fix: cherry pick response struct into map
rahmatrhd Mar 25, 2024
97233ef
fix: resolve metadata value
rahmatrhd Mar 25, 2024
93cd89d
refactor: move evaluate value logic to domain
rahmatrhd Mar 25, 2024
833eff6
fix: make appealMetadata concurent safe
rahmatrhd Mar 25, 2024
6bca409
feat: use context in http fetch
rahmatrhd Mar 25, 2024
534f2d3
feat!: move metadata sources config into policy.appeal
rahmatrhd Mar 25, 2024
ebbc248
refactor: revert debugging leftover
rahmatrhd Mar 25, 2024
6c51b4a
lint: fix lint errors
rahmatrhd Mar 25, 2024
60d5025
feat: use reflection for evaluating metadata value
rahmatrhd Mar 26, 2024
f42ee6f
feat: remove sensitive values before sending response
rahmatrhd Mar 27, 2024
3a02025
fix: nil check for config.Auth in http pkg
rahmatrhd Mar 28, 2024
bb2d63c
test: increase coverage
rahmatrhd Mar 29, 2024
37a15ab
test: add unit test for appeal metadata
rahmatrhd Mar 31, 2024
a2900cc
lint: fix lint errors
rahmatrhd Mar 31, 2024
0246be1
test: add unit test for policy service
rahmatrhd Mar 31, 2024
36019e2
test: add unit test for metadata source encrypt & decrypt
rahmatrhd Mar 31, 2024
c6a9db3
feat: sending notification concurrently
Mar 18, 2024
581b6a5
test: update unit test
Mar 18, 2024
46a46ab
test: fix unit test
Mar 20, 2024
4ebe653
test: fix race data
Mar 20, 2024
81371ae
feat(notifier): retry mechanism on slack notif
Mar 20, 2024
fb37aa2
chore: update client
Mar 25, 2024
f67976c
chore: update round trip flow
idilhaq Mar 27, 2024
119c44f
chore: update status checking return flow
idilhaq Mar 27, 2024
3b56481
chore: set http config as configurable
Mar 27, 2024
334ede9
test: added unit test
Apr 1, 2024
22729fe
chore: update default retry count domain
Apr 1, 2024
0a95bb2
chore: update client http timeout
Apr 1, 2024
1045865
feat(log): sending audit log concurrently
Mar 25, 2024
689c5b9
test: update test
Mar 25, 2024
e64a471
test: fix test
Mar 25, 2024
b049ad2
Merge remote-tracking branch 'origin/appeal-metadata-enhancer' into n…
Apr 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 50 additions & 4 deletions api/handler/v1beta1/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ func (a *adapter) FromPolicyProto(p *guardianv1beta1.Policy) *domain.Policy {
if p.GetAppeal() != nil {
var durationOptions []domain.AppealDurationOption
var questions []domain.Question
var metadataSources map[string]*domain.AppealMetadataSource
for _, d := range p.GetAppeal().GetDurationOptions() {
option := domain.AppealDurationOption{
Name: d.GetName(),
Expand All @@ -328,13 +329,27 @@ func (a *adapter) FromPolicyProto(p *guardianv1beta1.Policy) *domain.Policy {
questions = append(questions, question)
}

if mds := p.GetAppeal().GetMetadataSources(); mds != nil {
metadataSources = make(map[string]*domain.AppealMetadataSource)
for key, metadataCfg := range mds {
metadataSources[key] = &domain.AppealMetadataSource{
Name: metadataCfg.GetName(),
Description: metadataCfg.GetDescription(),
Type: metadataCfg.GetType(),
Config: metadataCfg.GetConfig().AsInterface(),
Value: metadataCfg.GetValue().AsInterface(),
}
}
}

policy.AppealConfig = &domain.PolicyAppealConfig{
DurationOptions: durationOptions,
AllowOnBehalf: p.GetAppeal().GetAllowOnBehalf(),
Questions: questions,
AllowPermanentAccess: p.GetAppeal().GetAllowPermanentAccess(),
AllowActiveAccessExtensionIn: p.GetAppeal().GetAllowActiveAccessExtensionIn(),
AllowCreatorDetailsFailure: p.GetAppeal().GetAllowCreatorDetailsFailure(),
MetadataSources: metadataSources,
}
}

Expand Down Expand Up @@ -444,7 +459,11 @@ func (a *adapter) ToPolicyProto(p *domain.Policy) (*guardianv1beta1.Policy, erro
}
}

policyProto.Appeal = a.ToPolicyAppealConfigProto(p)
appealConfig, err := a.ToPolicyAppealConfigProto(p)
if err != nil {
return nil, fmt.Errorf("failed to convert appeal config to proto: %w", err)
}
policyProto.Appeal = appealConfig

if !p.CreatedAt.IsZero() {
policyProto.CreatedAt = timestamppb.New(p.CreatedAt)
Expand All @@ -456,9 +475,9 @@ func (a *adapter) ToPolicyProto(p *domain.Policy) (*guardianv1beta1.Policy, erro
return policyProto, nil
}

func (a *adapter) ToPolicyAppealConfigProto(p *domain.Policy) *guardianv1beta1.PolicyAppealConfig {
func (a *adapter) ToPolicyAppealConfigProto(p *domain.Policy) (*guardianv1beta1.PolicyAppealConfig, error) {
if p.AppealConfig == nil {
return nil
return nil, nil
}

policyAppealConfigProto := &guardianv1beta1.PolicyAppealConfig{}
Expand All @@ -485,7 +504,34 @@ func (a *adapter) ToPolicyAppealConfigProto(p *domain.Policy) *guardianv1beta1.P
Description: q.Description,
})
}
return policyAppealConfigProto

for key, metadataSource := range p.AppealConfig.MetadataSources {
if policyAppealConfigProto.MetadataSources == nil {
policyAppealConfigProto.MetadataSources = make(map[string]*guardianv1beta1.PolicyAppealConfig_MetadataSource)
}
policyAppealConfigProto.MetadataSources[key] = &guardianv1beta1.PolicyAppealConfig_MetadataSource{
Name: metadataSource.Name,
Description: metadataSource.Description,
Type: metadataSource.Type,
}

if metadataSource.Config != nil {
cfg, err := structpb.NewValue(metadataSource.Config)
if err != nil {
return nil, err
}
policyAppealConfigProto.MetadataSources[key].Config = cfg
}
if metadataSource.Value != nil {
value, err := structpb.NewValue(metadataSource.Value)
if err != nil {
return nil, err
}
policyAppealConfigProto.MetadataSources[key].Value = value
}
}

return policyAppealConfigProto, nil
}

func (a *adapter) FromResourceProto(r *guardianv1beta1.Resource) *domain.Resource {
Expand Down
2 changes: 1 addition & 1 deletion api/handler/v1beta1/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type ProtoAdapter interface {
FromPolicyProto(*guardianv1beta1.Policy) *domain.Policy
ToPolicyProto(*domain.Policy) (*guardianv1beta1.Policy, error)

ToPolicyAppealConfigProto(policy *domain.Policy) *guardianv1beta1.PolicyAppealConfig
ToPolicyAppealConfigProto(policy *domain.Policy) (*guardianv1beta1.PolicyAppealConfig, error)

FromResourceProto(*guardianv1beta1.Resource) *domain.Resource
ToResourceProto(*domain.Resource) (*guardianv1beta1.Resource, error)
Expand Down
14 changes: 7 additions & 7 deletions api/handler/v1beta1/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ func (s *GRPCServer) ListPolicies(ctx context.Context, req *guardianv1beta1.List

policyProtos := []*guardianv1beta1.Policy{}
for _, p := range policies {
if p.IAM != nil {
p.IAM.Config = nil
}
p.RemoveSensitiveValues()
policyProto, err := s.adapter.ToPolicyProto(p)
if err != nil {
return nil, s.internalError(ctx, "failed to parse policy %v: %v", p.ID, err)
Expand All @@ -44,9 +42,7 @@ func (s *GRPCServer) GetPolicy(ctx context.Context, req *guardianv1beta1.GetPoli
}
}

if p.IAM != nil {
p.IAM.Config = nil
}
p.RemoveSensitiveValues()
policyProto, err := s.adapter.ToPolicyProto(p)
if err != nil {
return nil, s.internalError(ctx, "failed to parse policy: %v", err)
Expand Down Expand Up @@ -116,7 +112,11 @@ func (s *GRPCServer) GetPolicyPreferences(ctx context.Context, req *guardianv1be
}
}

appealConfigProto := s.adapter.ToPolicyAppealConfigProto(p)
p.RemoveSensitiveValues()
appealConfigProto, err := s.adapter.ToPolicyAppealConfigProto(p)
if err != nil {
return nil, s.internalError(ctx, "failed to parse policy preferences: %v", err)
}

return &guardianv1beta1.GetPolicyPreferencesResponse{
Appeal: appealConfigProto,
Expand Down
135 changes: 135 additions & 0 deletions api/handler/v1beta1/policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ func (s *GrpcHandlersSuite) TestListPolicies() {
Config: expectedIAMConfig,
Provider: "provider",
},
Appeal: &guardianv1beta1.PolicyAppealConfig{
MetadataSources: map[string]*guardianv1beta1.PolicyAppealConfig_MetadataSource{
"test-source": {
Name: "test-source",
},
},
},
},
},
}
Expand All @@ -38,6 +45,14 @@ func (s *GrpcHandlersSuite) TestListPolicies() {
Config: map[string]interface{}{"foo": "bar"},
Provider: "provider",
},
AppealConfig: &domain.PolicyAppealConfig{
MetadataSources: map[string]*domain.AppealMetadataSource{
"test-source": {
Name: "test-source",
Config: map[string]interface{}{"foo": "bar"},
},
},
},
},
}
s.policyService.EXPECT().Find(mock.MatchedBy(func(ctx context.Context) bool { return true })).Return(dummyPolicies, nil).Once()
Expand Down Expand Up @@ -403,11 +418,24 @@ func (s *GrpcHandlersSuite) TestCreatePolicy() {
Description: "Please provide the name of the team you are in",
},
},
MetadataSources: map[string]*domain.AppealMetadataSource{
"test-source": {
Name: "test-source",
Description: "test-description",
Type: "test-type",
Config: map[string]interface{}{"foo": "bar"},
Value: "test-value",
},
},
},
}
expectedVersion := uint(1)
expectedIAMConfig, err := structpb.NewValue(expectedPolicy.IAM.Config)
s.Require().NoError(err)
expectedMetadataSourceConfig, err := structpb.NewValue(expectedPolicy.AppealConfig.MetadataSources["test-source"].Config)
s.Require().NoError(err)
expectedMetadataSourceValue, err := structpb.NewValue(expectedPolicy.AppealConfig.MetadataSources["test-source"].Value)
s.Require().NoError(err)
expectedResponse := &guardianv1beta1.CreatePolicyResponse{
Policy: &guardianv1beta1.Policy{
Id: expectedPolicy.ID,
Expand Down Expand Up @@ -464,6 +492,15 @@ func (s *GrpcHandlersSuite) TestCreatePolicy() {
Description: "Please provide the name of the team you are in",
},
},
MetadataSources: map[string]*guardianv1beta1.PolicyAppealConfig_MetadataSource{
"test-source": {
Name: "test-source",
Description: "test-description",
Type: "test-type",
Config: expectedMetadataSourceConfig,
Value: expectedMetadataSourceValue,
},
},
},
CreatedAt: timestamppb.New(timeNow),
UpdatedAt: timestamppb.New(timeNow),
Expand Down Expand Up @@ -531,6 +568,15 @@ func (s *GrpcHandlersSuite) TestCreatePolicy() {
Description: "Please provide the name of the team you are in",
},
},
MetadataSources: map[string]*guardianv1beta1.PolicyAppealConfig_MetadataSource{
"test-source": {
Name: "test-source",
Description: "test-description",
Type: "test-type",
Config: expectedMetadataSourceConfig,
Value: expectedMetadataSourceValue,
},
},
},
},
}
Expand Down Expand Up @@ -798,3 +844,92 @@ func (s *GrpcHandlersSuite) TestUpdatePolicy() {
s.policyService.AssertExpectations(s.T())
})
}

func (s *GrpcHandlersSuite) TestGetPolicyPreferences() {
s.Run("should return policy preferences on success", func() {
s.setup()

dummyPolicy := &domain.Policy{
ID: "test-policy",
Version: 1,
AppealConfig: &domain.PolicyAppealConfig{
AllowActiveAccessExtensionIn: "24h",
AllowPermanentAccess: true,
MetadataSources: map[string]*domain.AppealMetadataSource{
"test-source": {
Name: "test-source",
Config: map[string]interface{}{"foo": "bar"},
},
},
},
}

s.policyService.EXPECT().
GetOne(mock.MatchedBy(func(ctx context.Context) bool { return true }), dummyPolicy.ID, dummyPolicy.Version).
Return(dummyPolicy, nil).Once()
expectedResponse := &guardianv1beta1.GetPolicyPreferencesResponse{
Appeal: &guardianv1beta1.PolicyAppealConfig{
AllowActiveAccessExtensionIn: "24h",
AllowPermanentAccess: true,
MetadataSources: map[string]*guardianv1beta1.PolicyAppealConfig_MetadataSource{
"test-source": {
Name: "test-source",
},
},
},
}

req := &guardianv1beta1.GetPolicyPreferencesRequest{
Id: dummyPolicy.ID,
Version: uint32(dummyPolicy.Version),
}
res, err := s.grpcServer.GetPolicyPreferences(context.Background(), req)

s.NoError(err)
s.Equal(expectedResponse, res)
s.Nil(res.Appeal.MetadataSources["test-source"].Config) // config that might contain sensitive value should be removed
s.policyService.AssertExpectations(s.T())
})

s.Run("should return not found error if policy not found", func() {
s.setup()

policyID := "test-policy"
policyVersion := uint(1)
expectedError := policy.ErrPolicyNotFound
s.policyService.EXPECT().
GetOne(mock.MatchedBy(func(ctx context.Context) bool { return true }), policyID, policyVersion).
Return(nil, expectedError).Once()

req := &guardianv1beta1.GetPolicyPreferencesRequest{
Id: policyID,
Version: uint32(policyVersion),
}
res, err := s.grpcServer.GetPolicyPreferences(context.Background(), req)

s.Equal(codes.NotFound, status.Code(err))
s.Nil(res)
s.policyService.AssertExpectations(s.T())
})

s.Run("should return internal error if policy service returns error", func() {
s.setup()

policyID := "test-policy"
policyVersion := uint(1)
expectedError := errors.New("random error")
s.policyService.EXPECT().
GetOne(mock.MatchedBy(func(ctx context.Context) bool { return true }), policyID, policyVersion).
Return(nil, expectedError).Once()

req := &guardianv1beta1.GetPolicyPreferencesRequest{
Id: policyID,
Version: uint32(policyVersion),
}
res, err := s.grpcServer.GetPolicyPreferences(context.Background(), req)

s.Equal(codes.Internal, status.Code(err))
s.Nil(res)
s.policyService.AssertExpectations(s.T())
})
}
Loading
Loading