From 02ac2870bc52e08ceff7029a8f0e788eb12dd20d Mon Sep 17 00:00:00 2001 From: Mike Mason Date: Mon, 17 Jul 2023 17:17:04 +0000 Subject: [PATCH] convert metlusr to idntusr --- internal/metal/models/idprefix.go | 3 +++ internal/metal/models/users.go | 45 +++++++++++++++++++++++++++---- internal/pubsub/subscriber.go | 24 +++++++++++++++-- 3 files changed, 65 insertions(+), 7 deletions(-) diff --git a/internal/metal/models/idprefix.go b/internal/metal/models/idprefix.go index 8dd3a59..39f99a7 100644 --- a/internal/metal/models/idprefix.go +++ b/internal/metal/models/idprefix.go @@ -9,4 +9,7 @@ const ( // IDPrefixUser defines the ID Prefix for a User. IDPrefixUser = "metlusr" + + // IdentityPrefixUser defines the ID Prefix for a User created with Identity API. + IdentityPrefixUser = "idntusr" ) diff --git a/internal/metal/models/users.go b/internal/metal/models/users.go index 5852cf2..8042c74 100644 --- a/internal/metal/models/users.go +++ b/internal/metal/models/users.go @@ -1,12 +1,19 @@ package models -import "go.infratographer.com/x/gidx" +import ( + "crypto/sha256" + "encoding/base64" + + "go.infratographer.com/x/gidx" +) const ( - MetalUserPrefix = "metlusr" + MetalUserIssuer = "https://auth.equinix.com/" + MetalUserIssuerIDPrefix = "auth|" ) type UserDetails struct { + id *gidx.PrefixedID ID string `json:"id"` FullName string `json:"full_name"` Organizations []*OrganizationDetails `json:"organizations"` @@ -15,9 +22,37 @@ type UserDetails struct { } func (d *UserDetails) PrefixedID() gidx.PrefixedID { - if d.ID == "" { - return gidx.NullPrefixedID + if d.id != nil { + return *d.id } - return gidx.PrefixedID(IDPrefixUser + "-" + d.ID) + nullID := gidx.NullPrefixedID + + d.id = &nullID + + if d.ID == "" { + return nullID + } + + id, err := GenerateSubjectID(IdentityPrefixUser, MetalUserIssuer, MetalUserIssuerIDPrefix+d.ID) + if err != nil { + return nullID + } + + d.id = &id + + return *d.id +} + +func GenerateSubjectID(prefix, iss, sub string) (gidx.PrefixedID, error) { + // Concatenate the iss and sub values, then hash them + issSub := iss + sub + issSubHash := sha256.Sum256([]byte(issSub)) + + digest := base64.RawURLEncoding.EncodeToString(issSubHash[:]) + + // Concatenate the prefix with the digest + out := prefix + "-" + digest + + return gidx.Parse(out) } diff --git a/internal/pubsub/subscriber.go b/internal/pubsub/subscriber.go index 8ae8164..bb2ec6f 100644 --- a/internal/pubsub/subscriber.go +++ b/internal/pubsub/subscriber.go @@ -6,11 +6,13 @@ import ( nc "github.com/nats-io/nats.go" "go.infratographer.com/x/events" + "go.infratographer.com/x/gidx" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" "go.uber.org/zap" + "go.equinixmetal.net/infra9-metal-bridge/internal/metal/models" "go.equinixmetal.net/infra9-metal-bridge/internal/service" "github.com/ThreeDotsLabs/watermill/message" @@ -173,7 +175,16 @@ func (s *Subscriber) handleTouchEvent(ctx context.Context, msg *message.Message, } if s.svc.IsUser(changeMsg.SubjectID) { - if err := s.svc.AssignUser(ctx, changeMsg.SubjectID, changeMsg.AdditionalSubjectIDs...); err != nil { + userUUID := changeMsg.SubjectID.String()[gidx.PrefixPartLength+1:] + + subjID, err := models.GenerateSubjectID(models.IdentityPrefixUser, models.MetalUserIssuer, models.MetalUserIssuerIDPrefix+userUUID) + if err != nil { + s.logger.Errorw("failed to convert user id to identity id", "user.id", changeMsg.SubjectID.String(), "error", err) + + return nil + } + + if err := s.svc.AssignUser(ctx, subjID, changeMsg.AdditionalSubjectIDs...); err != nil { // TODO: only return errors on retryable errors return err } @@ -206,7 +217,16 @@ func (s *Subscriber) handleDeleteEvent(ctx context.Context, msg *message.Message } if s.svc.IsUser(changeMsg.SubjectID) { - if err := s.svc.UnassignUser(ctx, changeMsg.SubjectID, changeMsg.AdditionalSubjectIDs...); err != nil { + userUUID := changeMsg.SubjectID.String()[gidx.PrefixPartLength+1:] + + subjID, err := models.GenerateSubjectID(models.IdentityPrefixUser, models.MetalUserIssuer, models.MetalUserIssuerIDPrefix+userUUID) + if err != nil { + s.logger.Errorw("failed to convert user id to identity id", "user.id", changeMsg.SubjectID.String(), "error", err) + + return nil + } + + if err := s.svc.UnassignUser(ctx, subjID, changeMsg.AdditionalSubjectIDs...); err != nil { // TODO: only return errors on retryable errors return err }