From ecb371fa9dece58db3b76e43bb52457fb6cadcf9 Mon Sep 17 00:00:00 2001 From: Mike Mason Date: Fri, 28 Jul 2023 22:55:48 +0000 Subject: [PATCH] update entx event hooks template Signed-off-by: Mike Mason --- entx/annotation.go | 10 ++- entx/template/event_hooks.tmpl | 109 ++++++++++++++++++++++++++++++--- 2 files changed, 109 insertions(+), 10 deletions(-) diff --git a/entx/annotation.go b/entx/annotation.go index fee7cf72..529654db 100644 --- a/entx/annotation.go +++ b/entx/annotation.go @@ -17,10 +17,11 @@ package entx // EventsHookAnnotationName is the value of the annotation when read during ent compilation var EventsHookAnnotationName = "INFRA9_EVENTHOOKS" -// EventsHookAnnotation provides a ent.Annotation spec. These shouldn't be set directly, you should use EventsHookAdditionalSubject() and EventsHookSubjectName instead +// EventsHookAnnotation provides a ent.Annotation spec. These shouldn't be set directly, you should use EventsHookRelationshipname() and EventsHookSubjectName instead type EventsHookAnnotation struct { SubjectName string IsAdditionalSubjectField bool + RelationshipName string } // Name implements the ent Annotation interface. @@ -35,6 +36,13 @@ func EventsHookAdditionalSubject() *EventsHookAnnotation { } } +// EventsHookRelationshipName sets the relationship name and marks the field as a relationship field +func EventsHookRelationshipName(s string) *EventsHookAnnotation { + return &EventsHookAnnotation{ + RelationshipName: s, + } +} + // EventsHookSubjectName sets the subject name that is where the messages for this object will be sent func EventsHookSubjectName(s string) *EventsHookAnnotation { return &EventsHookAnnotation{ diff --git a/entx/template/event_hooks.tmpl b/entx/template/event_hooks.tmpl index df0bfc0e..d96ccb20 100644 --- a/entx/template/event_hooks.tmpl +++ b/entx/template/event_hooks.tmpl @@ -17,6 +17,7 @@ return hook.{{ $node.Name }}Func(func(ctx context.Context, m *generated.{{ $node.Name }}Mutation) (ent.Value, error) { var err error additionalSubjects := []gidx.PrefixedID{} + relationships := []events.AuthRelationshipRequest{} objID, ok := m.{{ $node.ID.MutationGet }}() if !ok { @@ -40,7 +41,7 @@ {{ $currentValue }} := "" {{ $f.Name }}, ok := m.{{ $f.MutationGet }}() {{- $annotation := $f.Annotations.INFRA9_EVENTHOOKS }} - {{- if $annotation.IsAdditionalSubjectField }} + {{- if or $annotation.IsAdditionalSubjectField $annotation.RelationshipName }} if !ok && !m.Op().Is(ent.OpCreate) { // since we are doing an update or delete and these fields didn't change, load the "old" value {{ $f.Name }}, err = m.{{ $f.MutationGetOld }}(ctx) @@ -50,10 +51,32 @@ } {{- if $f.Optional }} if {{ $f.Name }} != gidx.NullPrefixedID { - additionalSubjects = append(additionalSubjects, {{ $f.Name }}) + {{- if $annotation.IsAdditionalSubjectField }} + additionalSubjects = append(additionalSubjects, {{ $f.Name }}) + {{- end }} + + {{- if $annotation.RelationshipName }} + relationships = append(relationships, events.AuthRelationshipRequest{ + Action: events.WriteAuthRelationshipAction, + ObjectID: objID, + RelationshipName: "{{ $annotation.RelationshipName }}", + SubjectID: {{ $f.Name }}, + }) + {{- end }} } {{- else }} - additionalSubjects = append(additionalSubjects, {{ $f.Name }}) + {{- if $annotation.IsAdditionalSubjectField }} + additionalSubjects = append(additionalSubjects, {{ $f.Name }}) + {{- end }} + + {{- if $annotation.RelationshipName }} + relationships = append(relationships, events.AuthRelationshipRequest{ + Action: events.WriteAuthRelationshipAction, + ObjectID: objID, + RelationshipName: "{{ $annotation.RelationshipName }}", + SubjectID: {{ $f.Name }}, + }) + {{- end }} {{- end }} {{ end }} @@ -100,6 +123,29 @@ {{ end }} {{ end }} + for _, msg := range relationships { + var errors []error + + resp, err := m.EventsPublisher.PublishAuthRelationshipRequest(ctx, "{{ $nodeAnnotation.SubjectName }}", msg) + if err != nil { + errors = append(errors, err) + } + + if resp != nil { + if resp.Error() != nil { + errors = append(errors, err) + } + + errors = append(errors, resp.Message().Errors...) + } + + err = multierr.Combine(errors...) + + if err != nil { + return nil, fmt.Errorf("relationship request failed with errors: %w", err) + } + } + msg := events.ChangeMessage{ EventType: eventType(m.Op()), SubjectID: objID, @@ -114,7 +160,7 @@ return retValue, err } - if err := m.EventsPublisher.PublishChange(ctx, "{{ $nodeAnnotation.SubjectName }}", msg); err != nil { + if _, err := m.EventsPublisher.PublishChange(ctx, "{{ $nodeAnnotation.SubjectName }}", msg); err != nil { return nil, fmt.Errorf("failed to publish change: %w", err) } @@ -128,6 +174,7 @@ func(next ent.Mutator) ent.Mutator { return hook.{{ $node.Name }}Func(func(ctx context.Context, m *generated.{{ $node.Name }}Mutation) (ent.Value, error) { additionalSubjects := []gidx.PrefixedID{} + relationships := []events.AuthRelationshipRequest{} objID, ok := m.{{ $node.ID.MutationGet }}() if !ok { @@ -142,13 +189,35 @@ {{- range $f := $node.Fields }} {{- if not $f.Sensitive }} {{- $annotation := $f.Annotations.INFRA9_EVENTHOOKS }} - {{- if $annotation.IsAdditionalSubjectField }} + {{- if or $annotation.IsAdditionalSubjectField $annotation.RelationshipName }} {{- if $f.Optional }} if dbObj.{{ $f.MutationGet }} != gidx.NullPrefixedID { - additionalSubjects = append(additionalSubjects, dbObj.{{ $f.MutationGet }}) + {{- if $annotation.IsAdditionalSubjectField }} + additionalSubjects = append(additionalSubjects, dbObj.{{ $f.MutationGet }}) + {{- end }} + + {{- if $annotation.RelationshipName }} + relationships = append(relationships, events.AuthRelationshipRequest{ + Action: events.DeleteAuthRelationshipAction, + ObjectID: objID, + RelationshipName: "{{ $annotation.RelationshipName }}", + SubjectID: dbObj.{{ $f.MutationGet }}, + }) + {{- end }} } {{- else }} - additionalSubjects = append(additionalSubjects, dbObj.{{ $f.MutationGet }}) + {{- if $annotation.IsAdditionalSubjectField }} + additionalSubjects = append(additionalSubjects, dbObj.{{ $f.MutationGet }}) + {{- end }} + + {{- if $annotation.RelationshipName }} + relationships = append(relationships, events.AuthRelationshipRequest{ + Action: events.DeleteAuthRelationshipAction, + ObjectID: objID, + RelationshipName: "{{ $annotation.RelationshipName }}", + SubjectID: dbObj.{{ $f.MutationGet }}, + }) + {{- end }} {{- end }} {{ end }} {{ end }} @@ -160,6 +229,29 @@ return retValue, err } + for _, msg := range relationships { + var errors []error + + resp, err := m.EventsPublisher.PublishAuthRelationshipRequest(ctx, "{{ $nodeAnnotation.SubjectName }}", msg) + if err != nil { + errors = append(errors, err) + } + + if resp != nil { + if resp.Error() != nil { + errors = append(errors, err) + } + + errors = append(errors, resp.Message().Errors...) + } + + err = multierr.Combine(errors...) + + if err != nil { + return nil, fmt.Errorf("relationship request failed with errors: %w", err) + } + } + msg := events.ChangeMessage{ EventType: eventType(m.Op()), SubjectID: objID, @@ -167,8 +259,7 @@ Timestamp: time.Now().UTC(), } - - if err := m.EventsPublisher.PublishChange(ctx, "{{ $nodeAnnotation.SubjectName }}", msg); err != nil { + if _, err := m.EventsPublisher.PublishChange(ctx, "{{ $nodeAnnotation.SubjectName }}", msg); err != nil { return nil, fmt.Errorf("failed to publish change: %w", err) }