Skip to content

Commit

Permalink
Add #325 Integrate data agreement record endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
albinpa authored and georgepadayatti committed Oct 22, 2023
1 parent 77dee31 commit 0d264cb
Show file tree
Hide file tree
Showing 36 changed files with 1,662 additions and 651 deletions.
9 changes: 9 additions & 0 deletions src/common/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"strings"
"time"

"github.com/bb-consent/api/src/config"
"github.com/microcosm-cc/bluemonday"
)

Expand Down Expand Up @@ -221,3 +222,11 @@ func CalculateSHA1(data string) (string, error) {

return hashHex, err
}

// Http response
func ReturnHTTPResponse(resp interface{}, w http.ResponseWriter) {
response, _ := json.Marshal(resp)
w.Header().Set(config.ContentTypeHeader, config.ContentTypeJSON)
w.WriteHeader(http.StatusOK)
w.Write(response)
}
7 changes: 7 additions & 0 deletions src/config/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const (
IdpId = "idpId"
ApiKeyId = "apiKeyId"
IndividualHeaderKey = "X-ConsentBB-IndividualId"
RevisionId = "revisionId"
)

// Schemas
Expand Down Expand Up @@ -58,3 +59,9 @@ const (
Audit = "audit"
Onboard = "onboard"
)

// Data agreement record state
const (
Unsigned = "unsigned"
Signed = "signed"
)
15 changes: 15 additions & 0 deletions src/database/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,21 @@ func Init(config *config.Configuration) error {
return err
}

err = initCollection("dataAgreementRecords", []string{"id"}, true)
if err != nil {
return err
}

err = initCollection("signatures", []string{"id"}, true)
if err != nil {
return err
}

err = initCollection("dataAgreementRecordsHistories", []string{"id"}, true)
if err != nil {
return err
}

return nil
}

Expand Down
63 changes: 63 additions & 0 deletions src/v2/dataagreement_record/dataagreement_record.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package dataagreementrecord

import (
"net/http"
"strings"

"go.mongodb.org/mongo-driver/bson/primitive"
)

type DataAgreementRecord struct {
Id primitive.ObjectID `json:"id" bson:"_id,omitempty"`
DataAgreementId string `json:"dataAgreementId"`
DataAgreementRevisionId string `json:"dataAgreementRevisionId"`
DataAgreementRevisionHash string `json:"dataAgreementRevisionHash"`
DataAttributes []DataAttributeForDataAgreementRecord `json:"dataAttributes"`
IndividualId string `json:"individualId"`
OptIn bool `json:"optIn"`
State string `json:"state" valid:"required"`
SignatureId string `json:"signatureId"`
OrganisationId string `json:"-"`
IsDeleted bool `json:"-"`
}

type DataAttributeForDataAgreementRecord struct {
DataAttributeId string `json:"id"`
DataAttributeRevisionId string `json:"dataAttributeRevisionId"`
DataAttributeRevisionHash string `json:"dataAttributeRevisionHash"`
OptIn bool `json:"optIn"`
}

// DataAgreementRecordError is an error enumeration for create consent record API.
type DataAgreementRecordError int

const (
// IndividualIDIsMissingError indicates that the consent record query params is missing.
IndividualIdIsMissingError DataAgreementRecordError = iota
DataAgreementIdIsMissingError
RevisionIdIsMissingError
)

// Error returns the string representation of the error.
func (e DataAgreementRecordError) Error() string {
switch e {
case IndividualIdIsMissingError:
return "Query param individualId is missing!"
case DataAgreementIdIsMissingError:
return "Query param dataAgreementId is missing!"
case RevisionIdIsMissingError:
return "Query param revisionId is missing!"
default:
return "Unknown error!"
}
}

// ParseQueryParams
func ParseQueryParams(r *http.Request, paramName string, errorType DataAgreementRecordError) (paramValue string, err error) {
query := r.URL.Query()
values, ok := query[paramName]
if ok && len(strings.TrimSpace(values[0])) > 0 {
return values[0], nil
}
return "", errorType
}
91 changes: 91 additions & 0 deletions src/v2/dataagreement_record/db.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package dataagreementrecord

import (
"context"

"github.com/bb-consent/api/src/common"
"github.com/bb-consent/api/src/database"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
)

func Collection() *mongo.Collection {
return database.DB.Client.Database(database.DB.Name).Collection("dataAgreementRecords")
}

type DataAgreementRecordRepository struct {
DefaultFilter bson.M
}

// Init
func (darRepo *DataAgreementRecordRepository) Init(organisationId string) {
darRepo.DefaultFilter = bson.M{"organisationid": organisationId, "isdeleted": false}
}

// Add Adds the data agreement record to the db
func (darRepo *DataAgreementRecordRepository) Add(dataAgreementRecord DataAgreementRecord) (DataAgreementRecord, error) {

_, err := Collection().InsertOne(context.TODO(), dataAgreementRecord)
if err != nil {
return DataAgreementRecord{}, err
}

return dataAgreementRecord, nil
}

// Get Gets a single data agreement record
func (darRepo *DataAgreementRecordRepository) Get(dataAgreementRecordID string) (DataAgreementRecord, error) {
dataAgreementRecordId, err := primitive.ObjectIDFromHex(dataAgreementRecordID)
if err != nil {
return DataAgreementRecord{}, err
}

filter := common.CombineFilters(darRepo.DefaultFilter, bson.M{"_id": dataAgreementRecordId})

var result DataAgreementRecord
err = Collection().FindOne(context.TODO(), filter).Decode(&result)

return result, err
}

// Update Updates the data agreement record
func (darRepo *DataAgreementRecordRepository) Update(dataAgreementRecord DataAgreementRecord) (DataAgreementRecord, error) {

filter := common.CombineFilters(darRepo.DefaultFilter, bson.M{"_id": dataAgreementRecord.Id})
update := bson.M{"$set": dataAgreementRecord}

_, err := Collection().UpdateOne(context.TODO(), filter, update)
if err != nil {
return dataAgreementRecord, err
}
return dataAgreementRecord, err
}

// Get Gets a single data agreement record by data agreement id and individual id
func (darRepo *DataAgreementRecordRepository) GetByDataAgreementIdandIndividualId(dataAgreementId string, individualId string) (DataAgreementRecord, error) {

filter := common.CombineFilters(darRepo.DefaultFilter, bson.M{"individualid": individualId, "dataagreementid": dataAgreementId})

var result DataAgreementRecord
err := Collection().FindOne(context.TODO(), filter).Decode(&result)

return result, err
}

// Deletes all the data agreement records of individual
func (darRepo *DataAgreementRecordRepository) DeleteAllRecordsForIndividual(individualId string) error {

filter := common.CombineFilters(darRepo.DefaultFilter, bson.M{"individualid": individualId})

// Update to set IsDeleted to true
update := bson.M{
"$set": bson.M{
"isdeleted": true,
},
}

_, err := Collection().UpdateMany(context.TODO(), filter, update)

return err
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package dataagreementrecordhistory

import (
"fmt"
"log"

"github.com/bb-consent/api/src/org"
"github.com/bb-consent/api/src/v2/dataagreement"
)

// DataAgreementRecordsHistory
type DataAgreementRecordsHistory struct {
Id string `json:"id" bson:"_id,omitempty"`
OrganisationId string `json:"organisationId"`
DataAgreementId string `json:"dataAgreementId"`
Log string `json:"log"`
Timestamp string `json:"timestamp"`
}

func DataAgreementRecordHistoryAdd(darH DataAgreementRecordsHistory, optIn bool) error {
o, err := org.Get(darH.OrganisationId)
if err != nil {
return err
}
// Repository
darepo := dataagreement.DataAgreementRepository{}
darepo.Init(darH.OrganisationId)

dataAgreement, err := darepo.Get(darH.DataAgreementId)
if err != nil {
return err
}

if optIn {
value := "Allow"
darH.Log = fmt.Sprintf("Updated consent value to <%s> for the purpose <%s> in organization <%s>",
value, dataAgreement.Purpose, o.Name)
} else {
value := "Disallow"
darH.Log = fmt.Sprintf("Updated consent value to <%s> for the purpose <%s> in organization <%s>",
value, dataAgreement.Purpose, o.Name)
}
log.Printf("The log is: %s", darH.Log)

_, err = Add(darH)
if err != nil {
return err
}
return nil

}
25 changes: 25 additions & 0 deletions src/v2/dataagreement_record_history/db.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package dataagreementrecordhistory

import (
"context"
"time"

"github.com/bb-consent/api/src/database"
"go.mongodb.org/mongo-driver/mongo"
)

func Collection() *mongo.Collection {
return database.DB.Client.Database(database.DB.Name).Collection("dataAgreementRecordsHistories")
}

// Add Adds the Data Agreement Records History to the db
func Add(dataAgreementRecordsHistory DataAgreementRecordsHistory) (DataAgreementRecordsHistory, error) {

dataAgreementRecordsHistory.Timestamp = time.Now().UTC().Format("2006-01-02T15:04:05Z")
_, err := Collection().InsertOne(context.TODO(), dataAgreementRecordsHistory)
if err != nil {
return DataAgreementRecordsHistory{}, err
}

return dataAgreementRecordsHistory, nil
}
55 changes: 55 additions & 0 deletions src/v2/handler/service/service_create_blank_signature_object.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package service

import (
"encoding/json"
"fmt"
"net/http"

"github.com/bb-consent/api/src/common"
"github.com/bb-consent/api/src/config"
daRecord "github.com/bb-consent/api/src/v2/dataagreement_record"
"github.com/bb-consent/api/src/v2/revision"
"github.com/bb-consent/api/src/v2/signature"
"github.com/gorilla/mux"
)

type createBlankSignatureResp struct {
Signature signature.Signature `json:"signature"`
}

func ServiceCreateBlankSignature(w http.ResponseWriter, r *http.Request) {

// Headers
organisationId := common.Sanitize(r.Header.Get(config.OrganizationId))

dataAgreementRecordId := common.Sanitize(mux.Vars(r)[config.DataAgreementRecordId])

// Repository
darRepo := daRecord.DataAgreementRecordRepository{}
darRepo.Init(organisationId)

// Get latest revision for data agreement record
daRecordRevision, err := revision.GetLatestByObjectId(dataAgreementRecordId)
if err != nil {
m := fmt.Sprintf("Failed to fetch revision for data agreement record: %v", dataAgreementRecordId)
common.HandleErrorV2(w, http.StatusInternalServerError, m, err)
return
}
// create signature for data agreement record
toBeCreatedSignature, err := signature.CreateSignatureForObject("revision", daRecordRevision.Id.Hex(), false, daRecordRevision, false, signature.Signature{})
if err != nil {
m := fmt.Sprintf("Failed to create signature for data agreement record: %v", dataAgreementRecordId)
common.HandleErrorV2(w, http.StatusInternalServerError, m, err)
return
}

// Creating response
resp := createBlankSignatureResp{
Signature: toBeCreatedSignature,
}

response, _ := json.Marshal(resp)
w.Header().Set(config.ContentTypeHeader, config.ContentTypeJSON)
w.WriteHeader(http.StatusOK)
w.Write(response)
}
Loading

0 comments on commit 0d264cb

Please sign in to comment.