-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add #343 Add individual endpoints in service
- Loading branch information
1 parent
eb0e73c
commit 0e07755
Showing
6 changed files
with
343 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package individual | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
"log" | ||
"net/http" | ||
|
||
"github.com/asaskevich/govalidator" | ||
"github.com/bb-consent/api/src/common" | ||
"github.com/bb-consent/api/src/config" | ||
"github.com/bb-consent/api/src/v2/individual" | ||
"go.mongodb.org/mongo-driver/bson/primitive" | ||
) | ||
|
||
func createIamRegisterRequestFromAddRequestBody(requestBody addServiceIndividualReq, iamRegReq iamIndividualRegisterReq) iamIndividualRegisterReq { | ||
|
||
iamRegReq.Username = requestBody.Individual.Email | ||
iamRegReq.Firstname = requestBody.Individual.Name | ||
iamRegReq.Email = requestBody.Individual.Email | ||
iamRegReq.Enabled = true | ||
iamRegReq.RequiredActions = []string{"UPDATE_PASSWORD"} | ||
|
||
return iamRegReq | ||
} | ||
func updateIndividualFromAddRequestBody(requestBody addServiceIndividualReq, newIndividual individual.Individual) individual.Individual { | ||
newIndividual.ExternalId = requestBody.Individual.ExternalId | ||
newIndividual.ExternalIdType = requestBody.Individual.ExternalIdType | ||
newIndividual.IdentityProviderId = requestBody.Individual.IdentityProviderId | ||
newIndividual.Name = requestBody.Individual.Name | ||
newIndividual.Email = requestBody.Individual.Email | ||
newIndividual.Phone = requestBody.Individual.Phone | ||
|
||
return newIndividual | ||
} | ||
|
||
type addServiceIndividualReq struct { | ||
Individual individual.Individual `json:"individual"` | ||
} | ||
|
||
type addServiceIndividualResp struct { | ||
Individual individual.Individual `json:"individual"` | ||
} | ||
|
||
// ServiceCreateIndividual | ||
func ServiceCreateIndividual(w http.ResponseWriter, r *http.Request) { | ||
// Headers | ||
organisationId := r.Header.Get(config.OrganizationId) | ||
organisationId = common.Sanitize(organisationId) | ||
|
||
// Request body | ||
var individualReq addServiceIndividualReq | ||
b, _ := io.ReadAll(r.Body) | ||
defer r.Body.Close() | ||
json.Unmarshal(b, &individualReq) | ||
|
||
// Validate request body | ||
valid, err := govalidator.ValidateStruct(individualReq) | ||
if !valid { | ||
common.HandleErrorV2(w, http.StatusBadRequest, err.Error(), err) | ||
return | ||
} | ||
|
||
var iamRegReq iamIndividualRegisterReq | ||
|
||
iamRegReq = createIamRegisterRequestFromAddRequestBody(individualReq, iamRegReq) | ||
|
||
client := getClient() | ||
|
||
t, err := getAdminToken(client) | ||
if err != nil { | ||
log.Printf("Failed to get admin token, user: %v registration", individualReq.Individual.Email) | ||
common.HandleErrorV2(w, http.StatusBadRequest, err.Error(), err) | ||
return | ||
} | ||
|
||
iamId, err := registerUser(iamRegReq, t.AccessToken, client) | ||
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.Id = primitive.NewObjectID() | ||
newIndividual.IamId = iamId | ||
newIndividual = updateIndividualFromAddRequestBody(individualReq, newIndividual) | ||
newIndividual.OrganisationId = organisationId | ||
newIndividual.IsDeleted = false | ||
newIndividual.IsOnboardedFromId = false | ||
|
||
// Repository | ||
individualRepo := individual.IndividualRepository{} | ||
individualRepo.Init(organisationId) | ||
|
||
// Save the individual to db | ||
savedIndividual, err := individualRepo.Add(newIndividual) | ||
if err != nil { | ||
m := fmt.Sprintf("Failed to create new individual: %v", newIndividual.Name) | ||
common.HandleErrorV2(w, http.StatusInternalServerError, m, err) | ||
return | ||
} | ||
|
||
resp := addServiceIndividualResp{ | ||
Individual: savedIndividual, | ||
} | ||
|
||
response, _ := json.Marshal(resp) | ||
w.Header().Set(config.ContentTypeHeader, config.ContentTypeJSON) | ||
w.WriteHeader(http.StatusOK) | ||
w.Write(response) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package individual | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
"log" | ||
"net/http" | ||
|
||
"github.com/bb-consent/api/src/common" | ||
"github.com/bb-consent/api/src/config" | ||
"github.com/bb-consent/api/src/v2/individual" | ||
"github.com/bb-consent/api/src/v2/paginate" | ||
) | ||
|
||
type listServiceIndividualsResp struct { | ||
Individuals interface{} `json:"individuals"` | ||
Pagination paginate.Pagination `json:"pagination"` | ||
} | ||
|
||
// ServiceListIndividuals | ||
func ServiceListIndividuals(w http.ResponseWriter, r *http.Request) { | ||
fmt.Println() | ||
|
||
organisationId := r.Header.Get(config.OrganizationId) | ||
organisationId = common.Sanitize(organisationId) | ||
|
||
// Repository | ||
individualRepo := individual.IndividualRepository{} | ||
individualRepo.Init(organisationId) | ||
|
||
// Query params | ||
offset, limit := paginate.ParsePaginationQueryParams(r) | ||
log.Printf("Offset: %v and limit: %v\n", offset, limit) | ||
|
||
var resp listServiceIndividualsResp | ||
|
||
// Return all individuals | ||
var individuals []individual.Individual | ||
query := paginate.PaginateDBObjectsQuery{ | ||
Filter: individualRepo.DefaultFilter, | ||
Collection: individual.Collection(), | ||
Context: context.Background(), | ||
Limit: limit, | ||
Offset: offset, | ||
} | ||
result, err := paginate.PaginateDBObjects(query, &individuals) | ||
if err != nil { | ||
if errors.Is(err, paginate.EmptyDBError) { | ||
emptyIndividuals := make([]interface{}, 0) | ||
resp = listServiceIndividualsResp{ | ||
Individuals: emptyIndividuals, | ||
Pagination: result.Pagination, | ||
} | ||
common.ReturnHTTPResponse(resp, w) | ||
return | ||
} | ||
m := "Failed to paginate data attribute" | ||
common.HandleErrorV2(w, http.StatusInternalServerError, m, err) | ||
return | ||
|
||
} | ||
resp = listServiceIndividualsResp{ | ||
Individuals: result.Items, | ||
Pagination: result.Pagination, | ||
} | ||
common.ReturnHTTPResponse(resp, w) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package individual | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"net/http" | ||
|
||
"github.com/bb-consent/api/src/common" | ||
"github.com/bb-consent/api/src/config" | ||
"github.com/bb-consent/api/src/v2/individual" | ||
"github.com/gorilla/mux" | ||
) | ||
|
||
type readServiceIndividualResp struct { | ||
Individual individual.Individual `json:"individual"` | ||
} | ||
|
||
func ServiceReadIndividual(w http.ResponseWriter, r *http.Request) { | ||
// Headers | ||
organisationId := r.Header.Get(config.OrganizationId) | ||
organisationId = common.Sanitize(organisationId) | ||
|
||
individualId := mux.Vars(r)[config.IndividualId] | ||
individualId = common.Sanitize(individualId) | ||
|
||
// Repository | ||
individualRepo := individual.IndividualRepository{} | ||
individualRepo.Init(organisationId) | ||
|
||
individual, err := individualRepo.Get(individualId) | ||
if err != nil { | ||
m := fmt.Sprintf("Failed to fetch individual: %v", individualId) | ||
common.HandleErrorV2(w, http.StatusInternalServerError, m, err) | ||
return | ||
} | ||
|
||
resp := readServiceIndividualResp{ | ||
Individual: individual, | ||
} | ||
|
||
response, _ := json.Marshal(resp) | ||
w.Header().Set(config.ContentTypeHeader, config.ContentTypeJSON) | ||
w.WriteHeader(http.StatusOK) | ||
w.Write(response) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package individual | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
"net/http" | ||
|
||
"github.com/asaskevich/govalidator" | ||
"github.com/bb-consent/api/src/common" | ||
"github.com/bb-consent/api/src/config" | ||
"github.com/bb-consent/api/src/v2/individual" | ||
"github.com/gorilla/mux" | ||
) | ||
|
||
func updateIamUpdateRequestFromUpdateRequestBody(requestBody updateServiceIndividualReq) iamIndividualUpdateReq { | ||
var iamIndividualReq iamIndividualUpdateReq | ||
|
||
iamIndividualReq.Username = requestBody.Individual.Email | ||
iamIndividualReq.Firstname = requestBody.Individual.Name | ||
iamIndividualReq.Email = requestBody.Individual.Email | ||
|
||
return iamIndividualReq | ||
} | ||
|
||
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 | ||
|
||
return tobeUpdatedIndividual | ||
} | ||
|
||
type updateServiceIndividualReq struct { | ||
Individual individual.Individual `json:"individual"` | ||
} | ||
|
||
type updateServiceIndividualResp struct { | ||
Individual individual.Individual `json:"individual"` | ||
} | ||
|
||
func ServiceUpdateIndividual(w http.ResponseWriter, r *http.Request) { | ||
// Headers | ||
organisationId := r.Header.Get(config.OrganizationId) | ||
organisationId = common.Sanitize(organisationId) | ||
|
||
individualId := mux.Vars(r)[config.IndividualId] | ||
individualId = common.Sanitize(individualId) | ||
|
||
// Request body | ||
var individualReq updateServiceIndividualReq | ||
b, _ := io.ReadAll(r.Body) | ||
defer r.Body.Close() | ||
json.Unmarshal(b, &individualReq) | ||
|
||
// Validate request body | ||
// validating request payload | ||
valid, err := govalidator.ValidateStruct(individualReq) | ||
if !valid { | ||
common.HandleErrorV2(w, http.StatusBadRequest, err.Error(), err) | ||
return | ||
} | ||
|
||
// Repository | ||
individualRepo := individual.IndividualRepository{} | ||
individualRepo.Init(organisationId) | ||
|
||
tobeUpdatedIndividual, err := individualRepo.Get(individualId) | ||
if err != nil { | ||
m := fmt.Sprintf("Failed to fetch individual: %v", individualId) | ||
common.HandleErrorV2(w, http.StatusInternalServerError, m, err) | ||
return | ||
} | ||
|
||
iamUpdateReq := updateIamUpdateRequestFromUpdateRequestBody(individualReq) | ||
|
||
err = updateIamIndividual(iamUpdateReq, tobeUpdatedIndividual.IamId) | ||
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, 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) | ||
return | ||
} | ||
|
||
resp := updateServiceIndividualResp{ | ||
Individual: savedIndividual, | ||
} | ||
|
||
response, _ := json.Marshal(resp) | ||
w.Header().Set(config.ContentTypeHeader, config.ContentTypeJSON) | ||
w.WriteHeader(http.StatusOK) | ||
w.Write(response) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters