Skip to content

Commit a3d2cac

Browse files
authored
Merge pull request #144 from linuxfoundation/feat/skip-enrichment-header
feat: add X-Skip-Enrichment header for committee member writes
2 parents 8791884 + 86d26f1 commit a3d2cac

20 files changed

Lines changed: 214 additions & 100 deletions

File tree

cmd/committee-api/design/committee.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ var _ = dsl.Service("committee-service", func() {
304304
VersionAttribute()
305305
XSyncAttribute()
306306
SkipNotificationAttribute()
307+
SkipEnrichmentAttribute()
307308
CommitteeUIDAttribute()
308309

309310
CommitteeMemberCreateAttributes()
@@ -326,6 +327,7 @@ var _ = dsl.Service("committee-service", func() {
326327
dsl.Header("bearer_token:Authorization")
327328
dsl.Header("x_sync:X-Sync")
328329
dsl.Header("skip_notification:X-Skip-Notification")
330+
dsl.Header("skip_enrichment:X-Skip-Enrichment")
329331
dsl.Response(dsl.StatusCreated)
330332
dsl.Response("BadRequest", dsl.StatusBadRequest)
331333
dsl.Response("NotFound", dsl.StatusNotFound)
@@ -490,6 +492,7 @@ var _ = dsl.Service("committee-service", func() {
490492
VersionAttribute()
491493
IfMatchAttribute()
492494
XSyncAttribute()
495+
SkipEnrichmentAttribute()
493496
CommitteeUIDAttribute()
494497
MemberUIDAttribute()
495498

@@ -514,6 +517,7 @@ var _ = dsl.Service("committee-service", func() {
514517
dsl.Header("bearer_token:Authorization")
515518
dsl.Header("if_match:If-Match")
516519
dsl.Header("x_sync:X-Sync")
520+
dsl.Header("skip_enrichment:X-Skip-Enrichment")
517521
dsl.Response(dsl.StatusOK)
518522
dsl.Response("BadRequest", dsl.StatusBadRequest)
519523
dsl.Response("NotFound", dsl.StatusNotFound)

cmd/committee-api/design/type.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,15 @@ func SkipNotificationAttribute() {
388388
})
389389
}
390390

391+
// SkipEnrichmentAttribute is the DSL attribute for skipping auth-service enrichment on
392+
// committee member writes (email→username lookup and profile metadata backfill).
393+
func SkipEnrichmentAttribute() {
394+
dsl.Attribute("skip_enrichment", dsl.Boolean, "When true, skip auth-service enrichment: the username, name, and avatar from the request body are stored as-is without email→username lookup or profile metadata backfill. Intended for trusted sync callers.", func() {
395+
dsl.Default(false)
396+
dsl.Example(true)
397+
})
398+
}
399+
391400
// CreatedAtAttribute is the DSL attribute for creation timestamp.
392401
func CreatedAtAttribute() {
393402
dsl.Attribute("created_at", dsl.String, "The timestamp when the resource was created (read-only)", func() {

cmd/committee-api/service/committee_service.go

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -284,11 +284,12 @@ func (s *committeeServicesrvc) CreateCommitteeMember(ctx context.Context, p *com
284284
// Convert payload to domain model
285285
request := s.convertMemberPayloadToDomain(p)
286286

287-
// If no username was supplied, resolve it from email and enrich profile fields.
288-
s.enrichMember(ctx, request)
287+
if !p.SkipEnrichment {
288+
s.enrichMember(ctx, request)
289+
}
289290

290291
// Execute use case
291-
response, err := s.committeeWriterOrchestrator.CreateMember(ctx, request, p.XSync)
292+
response, err := s.committeeWriterOrchestrator.CreateMember(ctx, request, p.XSync, p.SkipEnrichment)
292293
if err != nil {
293294
return nil, wrapError(ctx, err)
294295
}
@@ -588,11 +589,12 @@ func (s *committeeServicesrvc) UpdateCommitteeMember(ctx context.Context, p *com
588589
// Convert payload to domain model
589590
committeeMember := s.convertPayloadToUpdateMember(p)
590591

591-
// If no username was supplied, resolve it from email and enrich profile fields.
592-
s.enrichMember(ctx, committeeMember)
592+
if !p.SkipEnrichment {
593+
s.enrichMember(ctx, committeeMember)
594+
}
593595

594596
// Execute use case
595-
updatedMember, err := s.committeeWriterOrchestrator.UpdateMember(ctx, committeeMember, parsedRevision, p.XSync)
597+
updatedMember, err := s.committeeWriterOrchestrator.UpdateMember(ctx, committeeMember, parsedRevision, p.XSync, p.SkipEnrichment)
596598
if err != nil {
597599
return nil, wrapError(ctx, err)
598600
}
@@ -939,7 +941,7 @@ func (s *committeeServicesrvc) AcceptInvite(ctx context.Context, p *committeeser
939941
}
940942
s.enrichMember(ctx, member)
941943

942-
response, err := s.committeeWriterOrchestrator.CreateMember(ctx, member, false)
944+
response, err := s.committeeWriterOrchestrator.CreateMember(ctx, member, false, false)
943945
if err != nil {
944946
return nil, wrapError(ctx, err)
945947
}
@@ -1159,7 +1161,7 @@ func (s *committeeServicesrvc) ApproveApplication(ctx context.Context, p *commit
11591161
member.SkipNotification = true
11601162
}
11611163

1162-
response, err := s.committeeWriterOrchestrator.CreateMember(ctx, member, false)
1164+
response, err := s.committeeWriterOrchestrator.CreateMember(ctx, member, false, false)
11631165
if err != nil {
11641166
return nil, wrapError(ctx, err)
11651167
}
@@ -1257,7 +1259,7 @@ func (s *committeeServicesrvc) JoinCommittee(ctx context.Context, p *committeese
12571259
s.enrichMember(ctx, member)
12581260
s.enrichMemberOrganization(ctx, member)
12591261

1260-
response, err := s.committeeWriterOrchestrator.CreateMember(ctx, member, p.XSync)
1262+
response, err := s.committeeWriterOrchestrator.CreateMember(ctx, member, p.XSync, false)
12611263
if err != nil {
12621264
return nil, wrapError(ctx, err)
12631265
}

cmd/committee-api/service/committee_service_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ func (m *mockCommitteeWriterOrchestrator) Delete(ctx context.Context, uid string
139139
return errs.NewUnexpected("not implemented for test")
140140
}
141141

142-
func (m *mockCommitteeWriterOrchestrator) CreateMember(ctx context.Context, member *model.CommitteeMember, sync bool) (*model.CommitteeMember, error) {
142+
func (m *mockCommitteeWriterOrchestrator) CreateMember(ctx context.Context, member *model.CommitteeMember, sync bool, skipEnrichment bool) (*model.CommitteeMember, error) {
143143
m.createMemberCalls = append(m.createMemberCalls, member)
144144
if m.createMemberErr != nil {
145145
return nil, m.createMemberErr
@@ -150,7 +150,7 @@ func (m *mockCommitteeWriterOrchestrator) CreateMember(ctx context.Context, memb
150150
return nil, errs.NewUnexpected("not implemented for test")
151151
}
152152

153-
func (m *mockCommitteeWriterOrchestrator) UpdateMember(ctx context.Context, member *model.CommitteeMember, revision uint64, sync bool) (*model.CommitteeMember, error) {
153+
func (m *mockCommitteeWriterOrchestrator) UpdateMember(ctx context.Context, member *model.CommitteeMember, revision uint64, sync bool, skipEnrichment bool) (*model.CommitteeMember, error) {
154154
m.updateMemberCalls = append(m.updateMemberCalls, updateMemberCall{member: member, revision: revision})
155155
if m.updateMemberErr != nil {
156156
return nil, m.updateMemberErr
@@ -166,7 +166,7 @@ func (m *mockCommitteeWriterOrchestrator) DeleteMember(ctx context.Context, uid
166166
// ReassignMember mirrors the real orchestrator: create the new holder, delete the old, and roll back
167167
// the created member (an extra delete) if the delete fails, so reassign tests can assert the calls.
168168
func (m *mockCommitteeWriterOrchestrator) ReassignMember(ctx context.Context, oldMemberUID string, oldRevision uint64, newMember *model.CommitteeMember, sync bool) (*model.CommitteeMember, error) {
169-
created, err := m.CreateMember(ctx, newMember, sync)
169+
created, err := m.CreateMember(ctx, newMember, sync, false)
170170
if err != nil {
171171
return nil, err
172172
}

cmd/committee-cli/commands/sync/total_members_attribute_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,10 @@ func (w *mockWriter) UpdateSettings(_ context.Context, s *model.CommitteeSetting
167167
return s, nil
168168
}
169169
func (w *mockWriter) Delete(_ context.Context, _ string, _ uint64, _ bool) error { return nil }
170-
func (w *mockWriter) CreateMember(_ context.Context, m *model.CommitteeMember, _ bool) (*model.CommitteeMember, error) {
170+
func (w *mockWriter) CreateMember(_ context.Context, m *model.CommitteeMember, _ bool, _ bool) (*model.CommitteeMember, error) {
171171
return m, nil
172172
}
173-
func (w *mockWriter) UpdateMember(_ context.Context, m *model.CommitteeMember, _ uint64, _ bool) (*model.CommitteeMember, error) {
173+
func (w *mockWriter) UpdateMember(_ context.Context, m *model.CommitteeMember, _ uint64, _ bool, _ bool) (*model.CommitteeMember, error) {
174174
return m, nil
175175
}
176176
func (w *mockWriter) DeleteMember(_ context.Context, _ string, _ uint64, _ bool, _ bool) error {
@@ -398,11 +398,11 @@ func (c *conditionalFailWriter) UpdateSettings(ctx context.Context, s *model.Com
398398
func (c *conditionalFailWriter) Delete(ctx context.Context, uid string, rev uint64, sync bool) error {
399399
return c.inner.Delete(ctx, uid, rev, sync)
400400
}
401-
func (c *conditionalFailWriter) CreateMember(ctx context.Context, m *model.CommitteeMember, sync bool) (*model.CommitteeMember, error) {
402-
return c.inner.CreateMember(ctx, m, sync)
401+
func (c *conditionalFailWriter) CreateMember(ctx context.Context, m *model.CommitteeMember, sync bool, skipEnrichment bool) (*model.CommitteeMember, error) {
402+
return c.inner.CreateMember(ctx, m, sync, skipEnrichment)
403403
}
404-
func (c *conditionalFailWriter) UpdateMember(ctx context.Context, m *model.CommitteeMember, rev uint64, sync bool) (*model.CommitteeMember, error) {
405-
return c.inner.UpdateMember(ctx, m, rev, sync)
404+
func (c *conditionalFailWriter) UpdateMember(ctx context.Context, m *model.CommitteeMember, rev uint64, sync bool, skipEnrichment bool) (*model.CommitteeMember, error) {
405+
return c.inner.UpdateMember(ctx, m, rev, sync, skipEnrichment)
406406
}
407407
func (c *conditionalFailWriter) DeleteMember(ctx context.Context, uid string, rev uint64, sync bool, skipNotification bool) error {
408408
return c.inner.DeleteMember(ctx, uid, rev, sync, skipNotification)

gen/committee_service/service.go

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)