Skip to content

Commit

Permalink
Fix #547 Support updation of individuals onboarded from external idp
Browse files Browse the repository at this point in the history
Add #553
  • Loading branch information
albinpa authored and georgepadayatti committed Nov 14, 2023
1 parent 5bd3765 commit 993a4e9
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 58 deletions.
29 changes: 16 additions & 13 deletions internal/handler/v2/config/individual/config_create_individual.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"io"
"log"
"net/http"
"strings"

"github.com/asaskevich/govalidator"
"github.com/bb-consent/api/internal/common"
Expand All @@ -15,7 +16,8 @@ import (
"go.mongodb.org/mongo-driver/bson/primitive"
)

func updateIndividualFromRequestBody(requestBody addIndividualReq, newIndividual individual.Individual) individual.Individual {
func updateIndividualFromRequestBody(requestBody addIndividualReq) individual.Individual {
var newIndividual individual.Individual
newIndividual.ExternalId = requestBody.Individual.ExternalId
newIndividual.ExternalIdType = requestBody.Individual.ExternalIdType
newIndividual.IdentityProviderId = requestBody.Individual.IdentityProviderId
Expand Down Expand Up @@ -63,21 +65,22 @@ func ConfigCreateIndividual(w http.ResponseWriter, r *http.Request) {
return
}

// Register user to keyclock
iamId, err := iam.RegisterUser(individualReq.Individual.Email, individualReq.Individual.Name)
if err != nil {
log.Printf("Failed to register user: %v err: %v", individualReq.Individual.Email, err)
common.HandleErrorV2(w, http.StatusBadRequest, err.Error(), err)
return
}

var newIndividual individual.Individual
newIndividual := updateIndividualFromRequestBody(individualReq)
newIndividual.Id = primitive.NewObjectID()
newIndividual.IamId = iamId
newIndividual = updateIndividualFromRequestBody(individualReq, newIndividual)
newIndividual.OrganisationId = organisationId
newIndividual.IsDeleted = false
newIndividual.IsOnboardedFromId = false
newIndividual.IsOnboardedFromIdp = false

if len(strings.TrimSpace(newIndividual.Email)) > 1 {
// Register user to keyclock
iamId, err := iam.RegisterUser(newIndividual.Email, newIndividual.Name)
if err != nil {
log.Printf("Failed to register user: %v err: %v", individualReq.Individual.Email, err)
common.HandleErrorV2(w, http.StatusBadRequest, err.Error(), err)
return
}
newIndividual.IamId = iamId
}

// Repository
individualRepo := individual.IndividualRepository{}
Expand Down
60 changes: 44 additions & 16 deletions internal/handler/v2/config/individual/config_update_individual.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"io"
"net/http"
"strings"

"github.com/asaskevich/govalidator"
"github.com/bb-consent/api/internal/common"
Expand All @@ -25,12 +26,24 @@ func validateUpdateIndividualRequestBody(IndividualReq updateIndividualReq) erro
}

func updateIndividualFromUpdateIndividualRequestBody(requestBody updateIndividualReq, tobeUpdatedIndividual individual.Individual) individual.Individual {
tobeUpdatedIndividual.ExternalId = requestBody.Individual.ExternalId
tobeUpdatedIndividual.ExternalIdType = requestBody.Individual.ExternalIdType
tobeUpdatedIndividual.IdentityProviderId = requestBody.Individual.IdentityProviderId
tobeUpdatedIndividual.Name = requestBody.Individual.Name
tobeUpdatedIndividual.Email = requestBody.Individual.Email
tobeUpdatedIndividual.Phone = requestBody.Individual.Phone
if len(strings.TrimSpace(requestBody.Individual.ExternalId)) > 1 {
tobeUpdatedIndividual.ExternalId = requestBody.Individual.ExternalId
}
if len(strings.TrimSpace(requestBody.Individual.ExternalIdType)) > 1 {
tobeUpdatedIndividual.ExternalIdType = requestBody.Individual.ExternalIdType
}
if len(strings.TrimSpace(requestBody.Individual.IdentityProviderId)) > 1 {
tobeUpdatedIndividual.IdentityProviderId = requestBody.Individual.IdentityProviderId
}
if len(strings.TrimSpace(requestBody.Individual.Name)) > 1 {
tobeUpdatedIndividual.Name = requestBody.Individual.Name
}
if len(strings.TrimSpace(requestBody.Individual.Email)) > 1 {
tobeUpdatedIndividual.Email = requestBody.Individual.Email
}
if len(strings.TrimSpace(requestBody.Individual.Phone)) > 1 {
tobeUpdatedIndividual.Phone = requestBody.Individual.Phone
}

return tobeUpdatedIndividual
}
Expand Down Expand Up @@ -68,24 +81,39 @@ func ConfigUpdateIndividual(w http.ResponseWriter, r *http.Request) {
individualRepo := individual.IndividualRepository{}
individualRepo.Init(organisationId)

tobeUpdatedIndividual, err := individualRepo.Get(individualId)
currentIndividual, err := individualRepo.Get(individualId)
if err != nil {
m := fmt.Sprintf("Failed to fetch individual: %v", individualId)
common.HandleErrorV2(w, http.StatusInternalServerError, m, err)
return
}

// Update individual in iam
err = iam.UpdateIamIndividual(individualReq.Individual.Name, tobeUpdatedIndividual.IamId, individualReq.Individual.Email)
if err != nil {
m := fmt.Sprintf("Failed to update IAM user by id:%v", individualId)
common.HandleErrorV2(w, http.StatusInternalServerError, m, err)
return
}
toBeUpdatedIndividual := updateIndividualFromUpdateIndividualRequestBody(individualReq, currentIndividual)

if currentIndividual.Name != toBeUpdatedIndividual.Name || currentIndividual.Email != toBeUpdatedIndividual.Email {

if len(strings.TrimSpace(currentIndividual.IamId)) > 1 {
// Update individual in iam
err = iam.UpdateIamIndividual(toBeUpdatedIndividual.Name, currentIndividual.IamId, toBeUpdatedIndividual.Email)
if err != nil {
m := fmt.Sprintf("Failed to update IAM user by id:%v", individualId)
common.HandleErrorV2(w, http.StatusInternalServerError, m, err)
return
}
} else if len(strings.TrimSpace(toBeUpdatedIndividual.Email)) > 1 {
// register individual in iam
iamId, err := iam.RegisterUser(toBeUpdatedIndividual.Email, toBeUpdatedIndividual.Name)
if err != nil {
m := fmt.Sprintf("Failed to create IAM user by id:%v", individualId)
common.HandleErrorV2(w, http.StatusInternalServerError, m, err)
return
}
toBeUpdatedIndividual.IamId = iamId
}

tobeUpdatedIndividual = updateIndividualFromUpdateIndividualRequestBody(individualReq, tobeUpdatedIndividual)
}

savedIndividual, err := individualRepo.Update(tobeUpdatedIndividual)
savedIndividual, err := individualRepo.Update(toBeUpdatedIndividual)
if err != nil {
m := fmt.Sprintf("Failed to update individual: %v", individualId)
common.HandleErrorV2(w, http.StatusInternalServerError, m, err)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ func createIndividualFromIdp(email string, externalId string, organisationId str
newIndividual.ExternalId = externalId
newIndividual.OrganisationId = organisationId
newIndividual.IsDeleted = false
newIndividual.IsOnboardedFromId = true
newIndividual.IsOnboardedFromIdp = true
newIndividual.IdentityProviderId = idpId

_, err := individualRepo.Add(newIndividual)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import (
"go.mongodb.org/mongo-driver/bson/primitive"
)

func updateIndividualFromAddRequestBody(requestBody addServiceIndividualReq, newIndividual individual.Individual) individual.Individual {
func updateIndividualFromAddRequestBody(requestBody addServiceIndividualReq) individual.Individual {
var newIndividual individual.Individual
newIndividual.ExternalId = requestBody.Individual.ExternalId
newIndividual.ExternalIdType = requestBody.Individual.ExternalIdType
newIndividual.IdentityProviderId = requestBody.Individual.IdentityProviderId
Expand Down Expand Up @@ -65,23 +66,21 @@ func ServiceCreateIndividual(w http.ResponseWriter, r *http.Request) {
return
}

var newIndividual individual.Individual
newIndividual := updateIndividualFromAddRequestBody(individualReq)
newIndividual.Id = primitive.NewObjectID()
newIndividual.IsDeleted = false
newIndividual.IsOnboardedFromId = false
newIndividual.IsOnboardedFromIdp = false
newIndividual.OrganisationId = organisationId

if len(strings.TrimSpace(individualReq.Individual.Email)) > 1 {
if len(strings.TrimSpace(newIndividual.Email)) > 1 {
// Register user to keyclock
iamId, err := iam.RegisterUser(individualReq.Individual.Email, individualReq.Individual.Name)
iamId, err := iam.RegisterUser(newIndividual.Email, newIndividual.Name)
if err != nil {
log.Printf("Failed to register user: %v err: %v", individualReq.Individual.Email, err)
log.Printf("Failed to register user: %v err: %v", newIndividual.Email, err)
common.HandleErrorV2(w, http.StatusBadRequest, err.Error(), err)
return
}

newIndividual.IamId = iamId
newIndividual = updateIndividualFromAddRequestBody(individualReq, newIndividual)
}

// Repository
Expand Down
59 changes: 44 additions & 15 deletions internal/handler/v2/service/individual/service_update_individual.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"io"
"net/http"
"strings"

"github.com/asaskevich/govalidator"
"github.com/bb-consent/api/internal/common"
Expand All @@ -15,12 +16,25 @@ import (
)

func updateIndividualFromUpdateIndividualServiceRequestBody(requestBody updateServiceIndividualReq, tobeUpdatedIndividual individual.Individual) individual.Individual {
tobeUpdatedIndividual.ExternalId = requestBody.Individual.ExternalId
tobeUpdatedIndividual.ExternalIdType = requestBody.Individual.ExternalIdType
tobeUpdatedIndividual.IdentityProviderId = requestBody.Individual.IdentityProviderId
tobeUpdatedIndividual.Name = requestBody.Individual.Name
tobeUpdatedIndividual.Email = requestBody.Individual.Email
tobeUpdatedIndividual.Phone = requestBody.Individual.Phone

if len(strings.TrimSpace(requestBody.Individual.ExternalId)) > 1 {
tobeUpdatedIndividual.ExternalId = requestBody.Individual.ExternalId
}
if len(strings.TrimSpace(requestBody.Individual.ExternalIdType)) > 1 {
tobeUpdatedIndividual.ExternalIdType = requestBody.Individual.ExternalIdType
}
if len(strings.TrimSpace(requestBody.Individual.IdentityProviderId)) > 1 {
tobeUpdatedIndividual.IdentityProviderId = requestBody.Individual.IdentityProviderId
}
if len(strings.TrimSpace(requestBody.Individual.Name)) > 1 {
tobeUpdatedIndividual.Name = requestBody.Individual.Name
}
if len(strings.TrimSpace(requestBody.Individual.Email)) > 1 {
tobeUpdatedIndividual.Email = requestBody.Individual.Email
}
if len(strings.TrimSpace(requestBody.Individual.Phone)) > 1 {
tobeUpdatedIndividual.Phone = requestBody.Individual.Phone
}

return tobeUpdatedIndividual
}
Expand Down Expand Up @@ -59,23 +73,38 @@ func ServiceUpdateIndividual(w http.ResponseWriter, r *http.Request) {
individualRepo := individual.IndividualRepository{}
individualRepo.Init(organisationId)

tobeUpdatedIndividual, err := individualRepo.Get(individualId)
currentIndividual, err := individualRepo.Get(individualId)
if err != nil {
m := fmt.Sprintf("Failed to fetch individual: %v", individualId)
common.HandleErrorV2(w, http.StatusInternalServerError, m, err)
return
}

err = iam.UpdateIamIndividual(individualReq.Individual.Name, tobeUpdatedIndividual.IamId, individualReq.Individual.Email)
if err != nil {
m := fmt.Sprintf("Failed to update IAM user by id:%v", individualId)
common.HandleErrorV2(w, http.StatusInternalServerError, m, err)
return
}
toBeUpdatedIndividual := updateIndividualFromUpdateIndividualServiceRequestBody(individualReq, currentIndividual)

if currentIndividual.Name != toBeUpdatedIndividual.Name || currentIndividual.Email != toBeUpdatedIndividual.Email {

if len(strings.TrimSpace(currentIndividual.IamId)) > 1 {
// Update individual in iam
err = iam.UpdateIamIndividual(toBeUpdatedIndividual.Name, currentIndividual.IamId, toBeUpdatedIndividual.Email)
if err != nil {
m := fmt.Sprintf("Failed to update IAM user by id:%v", individualId)
common.HandleErrorV2(w, http.StatusInternalServerError, m, err)
return
}
} else if len(strings.TrimSpace(toBeUpdatedIndividual.Email)) > 1 {
iamId, err := iam.RegisterUser(toBeUpdatedIndividual.Email, toBeUpdatedIndividual.Name)
if err != nil {
m := fmt.Sprintf("Failed to create IAM user by id:%v", individualId)
common.HandleErrorV2(w, http.StatusInternalServerError, m, err)
return
}
toBeUpdatedIndividual.IamId = iamId
}

tobeUpdatedIndividual = updateIndividualFromUpdateIndividualServiceRequestBody(individualReq, tobeUpdatedIndividual)
}

savedIndividual, err := individualRepo.Update(tobeUpdatedIndividual)
savedIndividual, err := individualRepo.Update(toBeUpdatedIndividual)
if err != nil {
m := fmt.Sprintf("Failed to update individual: %v", individualId)
common.HandleErrorV2(w, http.StatusInternalServerError, m, err)
Expand Down
8 changes: 4 additions & 4 deletions internal/individual/individuals.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ type Individual struct {
ExternalId string `json:"externalId"`
ExternalIdType string `json:"externalIdType"`
IdentityProviderId string `json:"identityProviderId"`
Name string `json:"name" valid:"required"`
Name string `json:"name"`
IamId string `json:"iamId"`
Email string `json:"email" valid:"required"`
Phone string `json:"phone" valid:"required"`
IsOnboardedFromId bool `json:"-"`
Email string `json:"email"`
Phone string `json:"phone"`
IsOnboardedFromIdp bool `json:"-"`
OrganisationId string `json:"-"`
IsDeleted bool `json:"-"`
}
Expand Down
2 changes: 1 addition & 1 deletion internal/middleware/authenticate.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func createIndividual(externalId string, r *http.Request, organisationId string,
newIndividual.ExternalId = externalId
newIndividual.Name = token.GetName(r)
newIndividual.OrganisationId = organisationId
newIndividual.IsOnboardedFromId = true
newIndividual.IsOnboardedFromIdp = true
newIndividual.IdentityProviderId = idpId

newIndividual, err := individualRepo.Add(newIndividual)
Expand Down
16 changes: 16 additions & 0 deletions internal/migrate/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/bb-consent/api/internal/apikey"
"github.com/bb-consent/api/internal/dataagreement"
"github.com/bb-consent/api/internal/idp"
"github.com/bb-consent/api/internal/individual"
"github.com/bb-consent/api/internal/org"
"github.com/bb-consent/api/internal/policy"
"go.mongodb.org/mongo-driver/bson"
Expand All @@ -23,6 +24,7 @@ func Migrate() {
migrateOrganisationIdInIDPCollection()
migrateExpiryTimestampInApiKeyCollection()
migrateUnusedFieldsFromOrganistaionColloction()
migrateIsOnboardedFromIDPInindividualCollection()
}

func migrateThirdPartyDataSharingToTrueInPolicyCollection() {
Expand Down Expand Up @@ -202,3 +204,17 @@ func migrateUnusedFieldsFromOrganistaionColloction() {
fmt.Println(err)
}
}

func migrateIsOnboardedFromIDPInindividualCollection() {
individualCollection := individual.Collection()

filter := bson.M{}
update := bson.M{
"$rename": bson.M{"isonboardedfromid": "isonboardedfromidp"},
}

_, err := individualCollection.UpdateMany(context.TODO(), filter, update)
if err != nil {
fmt.Println(err)
}
}

0 comments on commit 993a4e9

Please sign in to comment.