mirror of
https://github.com/optim-enterprises-bv/databunker.git
synced 2025-11-20 08:04:55 +00:00
all consent api was split into 3 object to make it more GDPR friendly
This commit is contained in:
@@ -7,14 +7,14 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
//"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
func (e mainEnv) consentAccept(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
func (e mainEnv) agreementAccept(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
address := ps.ByName("address")
|
||||
brief := ps.ByName("brief")
|
||||
mode := ps.ByName("mode")
|
||||
event := audit("consent accept for "+brief, address, mode, address)
|
||||
event := audit("agreement accept for "+brief, address, mode, address)
|
||||
defer func() { event.submit(e.db) }()
|
||||
|
||||
if validateMode(mode) == false {
|
||||
@@ -27,6 +27,15 @@ func (e mainEnv) consentAccept(w http.ResponseWriter, r *http.Request, ps httpro
|
||||
returnError(w, r, "bad brief format", 405, nil, event)
|
||||
return
|
||||
}
|
||||
exists, err := e.db.checkLegalBasis(brief)
|
||||
if err != nil {
|
||||
returnError(w, r, "internal error", 405, nil, event)
|
||||
return
|
||||
}
|
||||
if exists == false {
|
||||
returnError(w, r, "not found", 405, nil, event)
|
||||
return
|
||||
}
|
||||
|
||||
userTOKEN := ""
|
||||
if mode == "token" {
|
||||
@@ -69,32 +78,14 @@ func (e mainEnv) consentAccept(w http.ResponseWriter, r *http.Request, ps httpro
|
||||
}()
|
||||
|
||||
status := "yes"
|
||||
message := ""
|
||||
freetext := ""
|
||||
lawfulbasis := ""
|
||||
consentmethod := ""
|
||||
agreementmethod := ""
|
||||
referencecode := ""
|
||||
lastmodifiedby := ""
|
||||
starttime := int32(0)
|
||||
expiration := int32(0)
|
||||
if value, ok := records["message"]; ok {
|
||||
if value, ok := records["agreementmethod"]; ok {
|
||||
if reflect.TypeOf(value) == reflect.TypeOf("string") {
|
||||
message = value.(string)
|
||||
}
|
||||
}
|
||||
if value, ok := records["freetext"]; ok {
|
||||
if reflect.TypeOf(value) == reflect.TypeOf("string") {
|
||||
freetext = value.(string)
|
||||
}
|
||||
}
|
||||
if value, ok := records["lawfulbasis"]; ok {
|
||||
if reflect.TypeOf(value) == reflect.TypeOf("string") {
|
||||
lawfulbasis = value.(string)
|
||||
}
|
||||
}
|
||||
if value, ok := records["consentmethod"]; ok {
|
||||
if reflect.TypeOf(value) == reflect.TypeOf("string") {
|
||||
consentmethod = value.(string)
|
||||
agreementmethod = value.(string)
|
||||
}
|
||||
}
|
||||
if value, ok := records["referencecode"]; ok {
|
||||
@@ -134,8 +125,9 @@ func (e mainEnv) consentAccept(w http.ResponseWriter, r *http.Request, ps httpro
|
||||
case "phone":
|
||||
address = normalizePhone(address, e.conf.Sms.DefaultCountry)
|
||||
}
|
||||
newStatus, _ := e.db.createConsentRecord(userTOKEN, mode, address, brief, message, status, lawfulbasis, consentmethod,
|
||||
referencecode, freetext, lastmodifiedby, starttime, expiration)
|
||||
e.db.acceptAgreement(userTOKEN, mode, address, brief, status, agreementmethod,
|
||||
referencecode, lastmodifiedby, starttime, expiration)
|
||||
/*
|
||||
notifyURL := e.conf.Notification.NotificationURL
|
||||
if newStatus == true && len(notifyURL) > 0 {
|
||||
// change notificate on new record or if status change
|
||||
@@ -145,6 +137,7 @@ func (e mainEnv) consentAccept(w http.ResponseWriter, r *http.Request, ps httpro
|
||||
notifyConsentChange(notifyURL, brief, status, mode, address)
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
func (e mainEnv) consentWithdraw(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
@@ -164,6 +157,15 @@ func (e mainEnv) consentWithdraw(w http.ResponseWriter, r *http.Request, ps http
|
||||
returnError(w, r, "bad brief format", 405, nil, event)
|
||||
return
|
||||
}
|
||||
exists, err := e.db.checkLegalBasis(brief)
|
||||
if err != nil {
|
||||
returnError(w, r, "internal error", 405, nil, event)
|
||||
return
|
||||
}
|
||||
if exists == false {
|
||||
returnError(w, r, "not found", 405, nil, event)
|
||||
return
|
||||
}
|
||||
|
||||
userTOKEN := ""
|
||||
authResult := ""
|
||||
@@ -242,7 +244,7 @@ func (e mainEnv) consentWithdraw(w http.ResponseWriter, r *http.Request, ps http
|
||||
case "phone":
|
||||
address = normalizePhone(address, e.conf.Sms.DefaultCountry)
|
||||
}
|
||||
e.db.withdrawConsentRecord(userTOKEN, brief, mode, address, lastmodifiedby)
|
||||
e.db.withdrawAgreement(userTOKEN, brief, mode, address, lastmodifiedby)
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
w.WriteHeader(200)
|
||||
w.Write([]byte(`{"status":"ok"}`))
|
||||
@@ -255,6 +257,7 @@ func (e mainEnv) consentWithdraw(w http.ResponseWriter, r *http.Request, ps http
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
func (e mainEnv) consentAllUserRecords(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
address := ps.ByName("address")
|
||||
mode := ps.ByName("mode")
|
||||
@@ -370,7 +373,9 @@ func (e mainEnv) consentUserRecord(w http.ResponseWriter, r *http.Request, ps ht
|
||||
str := fmt.Sprintf(`{"status":"ok","data":%s}`, resultJSON)
|
||||
w.Write([]byte(str))
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
func (e mainEnv) consentFilterRecords(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
brief := ps.ByName("brief")
|
||||
event := audit("consent get all for "+brief, brief, "brief", brief)
|
||||
@@ -416,3 +421,4 @@ func (e mainEnv) consentBriefs(w http.ResponseWriter, r *http.Request, ps httpro
|
||||
str := fmt.Sprintf(`{"status":"ok","total":%d,"briefs":%s}`, numRecords, resultJSON)
|
||||
w.Write([]byte(str))
|
||||
}
|
||||
*/
|
||||
174
src/agreements_db.go
Normal file
174
src/agreements_db.go
Normal file
@@ -0,0 +1,174 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
//"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/paranoidguy/databunker/src/storage"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
type agreement struct {
|
||||
Creationtime int32 `json:"creationtime" structs:"creationtime"`
|
||||
Starttime int32 `json:"starttime" structs:"starttime"`
|
||||
Endtime int32 `json:"endtime" structs:"endtime"`
|
||||
When int32 `json:"when,omitempty" structs:"when"`
|
||||
Who string `json:"who,omitempty" structs:"who"`
|
||||
Mode string `json:"mode,omitempty" structs:"mode"`
|
||||
Token string `json:"token" structs:"token"`
|
||||
Brief string `json:"brief,omitempty" structs:"brief"`
|
||||
Status string `json:"status,omitempty" structs:"status"`
|
||||
Referencecode string `json:"referencecode,omitempty" structs:"referencecode,omitempty"`
|
||||
Lastmodifiedby string `json:"lastmodifiedby,omitempty" structs:"lastmodifiedby,omitempty"`
|
||||
Agreementmethod string `json:"agreementmethod,omitempty" structs:"agreementmethod"`
|
||||
}
|
||||
|
||||
func (dbobj dbcon) acceptAgreement(userTOKEN string, mode string, usercode string, brief string,
|
||||
status string, agreementmethod string, referencecode string, lastmodifiedby string,
|
||||
starttime int32, endtime int32) (bool, error) {
|
||||
now := int32(time.Now().Unix())
|
||||
bdoc := bson.M{}
|
||||
bdoc["when"] = now
|
||||
bdoc["status"] = status
|
||||
bdoc["endtime"] = endtime
|
||||
bdoc["lastmodifiedby"] = lastmodifiedby
|
||||
if len(referencecode) > 0 {
|
||||
bdoc["referencecode"] = referencecode
|
||||
}
|
||||
if len(userTOKEN) > 0 {
|
||||
// first check if this agreement exists, then update
|
||||
raw, err := dbobj.store.GetRecord2(storage.TblName.Agreements, "token", userTOKEN, "brief", brief)
|
||||
if err != nil {
|
||||
fmt.Printf("error to find:%s", err)
|
||||
return false, err
|
||||
}
|
||||
if raw != nil {
|
||||
dbobj.store.UpdateRecord2(storage.TblName.Agreements, "token", userTOKEN, "brief", brief, &bdoc, nil)
|
||||
if status != raw["status"].(string) {
|
||||
// status changed
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
} else {
|
||||
raw, err := dbobj.store.GetRecord2(storage.TblName.Agreements, "who", usercode, "brief", brief)
|
||||
if err != nil {
|
||||
fmt.Printf("error to find:%s", err)
|
||||
return false, err
|
||||
}
|
||||
if raw != nil {
|
||||
dbobj.store.UpdateRecord2(storage.TblName.Agreements, "who", usercode, "brief", brief, &bdoc, nil)
|
||||
if status != raw["status"].(string) {
|
||||
// status changed
|
||||
return true, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
bdoc["brief"] = brief
|
||||
bdoc["mode"] = mode
|
||||
bdoc["who"] = usercode
|
||||
bdoc["token"] = userTOKEN
|
||||
if len(agreementmethod) > 0 {
|
||||
bdoc["agreementmethod"] = agreementmethod
|
||||
} else {
|
||||
bdoc["agreementmethod"] = "api"
|
||||
}
|
||||
// in any case - insert record
|
||||
_, err := dbobj.store.CreateRecord(storage.TblName.Agreements, &bdoc)
|
||||
if err != nil {
|
||||
fmt.Printf("error to insert record: %s\n", err)
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// link consent record to userToken
|
||||
func (dbobj dbcon) linkAgreementRecords(userTOKEN string, mode string, usercode string) error {
|
||||
bdoc := bson.M{}
|
||||
bdoc["token"] = userTOKEN
|
||||
_, err := dbobj.store.UpdateRecord2(storage.TblName.Agreements, "token", "", "who", usercode, &bdoc, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (dbobj dbcon) withdrawAgreement(userTOKEN string, brief string, mode string, usercode string, lastmodifiedby string) error {
|
||||
now := int32(time.Now().Unix())
|
||||
// update date, status
|
||||
bdoc := bson.M{}
|
||||
bdoc["when"] = now
|
||||
bdoc["mode"] = mode
|
||||
bdoc["who"] = usercode
|
||||
bdoc["endtime"] = 0
|
||||
bdoc["status"] = "no"
|
||||
bdoc["lastmodifiedby"] = lastmodifiedby
|
||||
if len(userTOKEN) > 0 {
|
||||
fmt.Printf("%s %s\n", userTOKEN, brief)
|
||||
dbobj.store.UpdateRecord2(storage.TblName.Agreements, "token", userTOKEN, "brief", brief, &bdoc, nil)
|
||||
} else {
|
||||
dbobj.store.UpdateRecord2(storage.TblName.Agreements, "who", usercode, "brief", brief, &bdoc, nil)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// link consent to user?
|
||||
/*
|
||||
func (dbobj dbcon) listConsentRecords(userTOKEN string) ([]byte, int, error) {
|
||||
records, err := dbobj.store.GetList(storage.TblName.Agreements, "token", userTOKEN, 0, 0, "")
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
count := len(records)
|
||||
if count == 0 {
|
||||
return []byte("[]"), 0, err
|
||||
}
|
||||
resultJSON, err := json.Marshal(records)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
//fmt.Printf("Found multiple documents (array of pointers): %+v\n", results)
|
||||
return resultJSON, count, nil
|
||||
}
|
||||
*/
|
||||
|
||||
func (dbobj dbcon) viewAgreementRecord(userTOKEN string, brief string) ([]byte, error) {
|
||||
record, err := dbobj.store.GetRecord2(storage.TblName.Agreements, "token", userTOKEN, "brief", brief)
|
||||
if record == nil || err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resultJSON, err := json.Marshal(record)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//fmt.Printf("Found multiple documents (array of pointers): %+v\n", results)
|
||||
return resultJSON, nil
|
||||
}
|
||||
|
||||
func (dbobj dbcon) expireAgreementRecords(notifyURL string) error {
|
||||
records, err := dbobj.store.GetExpiring(storage.TblName.Agreements, "status", "yes")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, rec := range records {
|
||||
now := int32(time.Now().Unix())
|
||||
// update date, status
|
||||
bdoc := bson.M{}
|
||||
bdoc["when"] = now
|
||||
bdoc["status"] = "expired"
|
||||
userTOKEN := rec["token"].(string)
|
||||
brief := rec["brief"].(string)
|
||||
fmt.Printf("This Agreements record is expired: %s - %s\n", userTOKEN, brief)
|
||||
if len(userTOKEN) > 0 {
|
||||
fmt.Printf("%s %s\n", userTOKEN, brief)
|
||||
dbobj.store.UpdateRecord2(storage.TblName.Agreements, "token", userTOKEN, "brief", brief, &bdoc, nil)
|
||||
notifyConsentChange(notifyURL, brief, "expired", "token", userTOKEN)
|
||||
} else {
|
||||
usercode := rec["who"].(string)
|
||||
dbobj.store.UpdateRecord2(storage.TblName.Agreements, "who", usercode, "brief", brief, &bdoc, nil)
|
||||
notifyConsentChange(notifyURL, brief, "expired", rec["mode"].(string), usercode)
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -209,12 +209,22 @@ func (e mainEnv) setupRouter() *httprouter.Router {
|
||||
router.GET("/v1/requests/:mode/:address", e.getCustomUserRequests)
|
||||
router.GET("/v1/requests", e.getUserRequests)
|
||||
|
||||
router.GET("/v1/consent/:mode/:address", e.consentAllUserRecords)
|
||||
router.GET("/v1/consent/:mode/:address/:brief", e.consentUserRecord)
|
||||
router.GET("/v1/consents/:brief", e.consentFilterRecords)
|
||||
router.GET("/v1/consents", e.consentBriefs)
|
||||
router.POST("/v1/consent/:mode/:address/:brief", e.consentAccept)
|
||||
router.DELETE("/v1/consent/:mode/:address/:brief", e.consentWithdraw)
|
||||
router.GET("/v1/pactivity", e.pactivityList)
|
||||
router.POST("/v1/pactivity/:activity", e.pactivityCreate)
|
||||
router.DELETE("/v1/pactivity/:activity", e.pactivityDelete)
|
||||
router.POST("/v1/pactivity/:activity/:brief", e.pactivityLink)
|
||||
router.DELETE("/v1/pactivity/:activity/:brief", e.pactivityUnlink)
|
||||
|
||||
router.GET("/v1/lbasis", e.listLegalBasisRecords)
|
||||
router.POST("/v1/lbasis/:brief", e.createLegalBasis)
|
||||
router.DELETE("/v1/lbasis/:brief", e.deleteLegalBasis)
|
||||
|
||||
//router.GET("/v1/agreement/:mode/:address", e.pactivityUserReport)
|
||||
router.POST("/v1/agreement/:brief/:mode/:address", e.agreementAccept)
|
||||
router.DELETE("/v1/agreement/:brief/:mode/:address", e.consentWithdraw)
|
||||
|
||||
//router.GET("/v1/consent/:mode/:address", e.consentAllUserRecords)
|
||||
//router.GET("/v1/consent/:mode/:address/:brief", e.consentUserRecord)
|
||||
|
||||
router.POST("/v1/userapp/token/:token/:appname", e.userappNew)
|
||||
router.GET("/v1/userapp/token/:token/:appname", e.userappGet)
|
||||
@@ -305,7 +315,7 @@ func (e mainEnv) dbCleanupDo() {
|
||||
e.db.store.DeleteExpired0(storage.TblName.Audit, exp)
|
||||
}
|
||||
notifyURL := e.conf.Notification.NotificationURL
|
||||
e.db.expireConsentRecords(notifyURL)
|
||||
e.db.expireAgreementRecords(notifyURL)
|
||||
}
|
||||
|
||||
func (e mainEnv) dbCleanup() {
|
||||
|
||||
@@ -1,252 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
"github.com/paranoidguy/databunker/src/storage"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
type consentEvent struct {
|
||||
Creationtime int32 `json:"creationtime" structs:"creationtime"`
|
||||
Starttime int32 `json:"starttime" structs:"starttime"`
|
||||
Endtime int32 `json:"endtime" structs:"endtime"`
|
||||
When int32 `json:"when,omitempty" structs:"when"`
|
||||
Who string `json:"who,omitempty" structs:"who"`
|
||||
Mode string `json:"mode,omitempty" structs:"mode"`
|
||||
Token string `json:"token" structs:"token"`
|
||||
Brief string `json:"brief,omitempty" structs:"brief"`
|
||||
Status string `json:"status,omitempty" structs:"status"`
|
||||
Message string `json:"message,omitempty" structs:"message,omitempty"`
|
||||
Freetext string `json:"freetext,omitempty" structs:"freetext,omitempty"`
|
||||
Lawfulbasis string `json:"lawfulbasis,omitempty" structs:"lawfulbasis"`
|
||||
Consentmethod string `json:"consentmethod,omitempty" structs:"consentmethod"`
|
||||
Referencecode string `json:"referencecode,omitempty" structs:"referencecode,omitempty"`
|
||||
Lastmodifiedby string `json:"lastmodifiedby,omitempty" structs:"lastmodifiedby,omitempty"`
|
||||
}
|
||||
|
||||
func (dbobj dbcon) createConsentRecord(userTOKEN string, mode string, usercode string,
|
||||
brief string, message string, status string, lawfulbasis string, consentmethod string,
|
||||
referencecode string, freetext string, lastmodifiedby string, starttime int32, endtime int32) (bool, error) {
|
||||
now := int32(time.Now().Unix())
|
||||
bdoc := bson.M{}
|
||||
bdoc["when"] = now
|
||||
bdoc["status"] = status
|
||||
bdoc["endtime"] = endtime
|
||||
if len(lawfulbasis) > 0 {
|
||||
// in case of update, consent, use new value
|
||||
bdoc["lawfulbasis"] = lawfulbasis
|
||||
}
|
||||
if len(consentmethod) > 0 {
|
||||
bdoc["consentmethod"] = consentmethod
|
||||
}
|
||||
if len(referencecode) > 0 {
|
||||
bdoc["referencecode"] = referencecode
|
||||
}
|
||||
if len(freetext) > 0 {
|
||||
bdoc["freetext"] = freetext
|
||||
}
|
||||
bdoc["lastmodifiedby"] = lastmodifiedby
|
||||
if len(userTOKEN) > 0 {
|
||||
// first check if this consent exists, then update
|
||||
raw, err := dbobj.store.GetRecord2(storage.TblName.Consent, "token", userTOKEN, "brief", brief)
|
||||
if err != nil {
|
||||
fmt.Printf("error to find:%s", err)
|
||||
return false, err
|
||||
}
|
||||
if raw != nil {
|
||||
dbobj.store.UpdateRecord2(storage.TblName.Consent, "token", userTOKEN, "brief", brief, &bdoc, nil)
|
||||
if status != raw["status"].(string) {
|
||||
// status changed
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
} else {
|
||||
raw, err := dbobj.store.GetRecord2(storage.TblName.Consent, "who", usercode, "brief", brief)
|
||||
if err != nil {
|
||||
fmt.Printf("error to find:%s", err)
|
||||
return false, err
|
||||
}
|
||||
if raw != nil {
|
||||
dbobj.store.UpdateRecord2(storage.TblName.Consent, "who", usercode, "brief", brief, &bdoc, nil)
|
||||
if status != raw["status"].(string) {
|
||||
// status changed
|
||||
return true, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
if len(consentmethod) == 0 {
|
||||
consentmethod = "api"
|
||||
}
|
||||
if len(lawfulbasis) == 0 {
|
||||
lawfulbasis = "consent"
|
||||
}
|
||||
ev := consentEvent{
|
||||
Creationtime: now,
|
||||
Endtime: endtime,
|
||||
When: now,
|
||||
Who: usercode,
|
||||
Token: userTOKEN,
|
||||
Mode: mode,
|
||||
Brief: brief,
|
||||
Message: message,
|
||||
Status: status,
|
||||
Freetext: freetext,
|
||||
Lawfulbasis: lawfulbasis,
|
||||
Consentmethod: consentmethod,
|
||||
Referencecode: referencecode,
|
||||
Lastmodifiedby: lastmodifiedby,
|
||||
}
|
||||
// in any case - insert record
|
||||
_, err := dbobj.store.CreateRecord(storage.TblName.Consent, structs.Map(ev))
|
||||
if err != nil {
|
||||
fmt.Printf("error to insert record: %s\n", err)
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// link consent record to userToken
|
||||
func (dbobj dbcon) linkConsentRecords(userTOKEN string, mode string, usercode string) error {
|
||||
bdoc := bson.M{}
|
||||
bdoc["token"] = userTOKEN
|
||||
_, err := dbobj.store.UpdateRecord2(storage.TblName.Consent, "token", "", "who", usercode, &bdoc, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (dbobj dbcon) withdrawConsentRecord(userTOKEN string, brief string, mode string, usercode string, lastmodifiedby string) error {
|
||||
// brief can not be too long, may be hash it ?
|
||||
if len(brief) > 64 {
|
||||
return errors.New("Brief value is too long")
|
||||
}
|
||||
now := int32(time.Now().Unix())
|
||||
// update date, status
|
||||
bdoc := bson.M{}
|
||||
bdoc["when"] = now
|
||||
bdoc["mode"] = mode
|
||||
bdoc["who"] = usercode
|
||||
bdoc["endtime"] = 0
|
||||
bdoc["status"] = "no"
|
||||
bdoc["lastmodifiedby"] = lastmodifiedby
|
||||
if len(userTOKEN) > 0 {
|
||||
fmt.Printf("%s %s\n", userTOKEN, brief)
|
||||
dbobj.store.UpdateRecord2(storage.TblName.Consent, "token", userTOKEN, "brief", brief, &bdoc, nil)
|
||||
} else {
|
||||
dbobj.store.UpdateRecord2(storage.TblName.Consent, "who", usercode, "brief", brief, &bdoc, nil)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// link consent to user?
|
||||
|
||||
func (dbobj dbcon) listConsentRecords(userTOKEN string) ([]byte, int, error) {
|
||||
records, err := dbobj.store.GetList(storage.TblName.Consent, "token", userTOKEN, 0, 0, "")
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
count := len(records)
|
||||
if count == 0 {
|
||||
return []byte("[]"), 0, err
|
||||
}
|
||||
resultJSON, err := json.Marshal(records)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
//fmt.Printf("Found multiple documents (array of pointers): %+v\n", results)
|
||||
return resultJSON, count, nil
|
||||
}
|
||||
|
||||
func (dbobj dbcon) viewConsentRecord(userTOKEN string, brief string) ([]byte, error) {
|
||||
record, err := dbobj.store.GetRecord2(storage.TblName.Consent, "token", userTOKEN, "brief", brief)
|
||||
if record == nil || err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resultJSON, err := json.Marshal(record)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//fmt.Printf("Found multiple documents (array of pointers): %+v\n", results)
|
||||
return resultJSON, nil
|
||||
}
|
||||
|
||||
func (dbobj dbcon) filterConsentRecords(brief string, offset int32, limit int32) ([]byte, int64, error) {
|
||||
//var results []*auditEvent
|
||||
count, err := dbobj.store.CountRecords(storage.TblName.Consent, "brief", brief)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
if count == 0 {
|
||||
return []byte("[]"), 0, err
|
||||
}
|
||||
records, err := dbobj.store.GetList(storage.TblName.Consent, "brief", brief, offset, limit, "")
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
// we need to return only list of tokens
|
||||
var result []string
|
||||
for _, rec := range records {
|
||||
result = append(result, rec["token"].(string))
|
||||
}
|
||||
resultJSON, err := json.Marshal(result)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
//fmt.Printf("Found multiple documents (array of pointers): %+v\n", results)
|
||||
return resultJSON, count, nil
|
||||
}
|
||||
|
||||
func (dbobj dbcon) getConsentBriefs() ([]byte, int64, error) {
|
||||
records, err := dbobj.store.GetUniqueList(storage.TblName.Consent, "brief")
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
count := int64(len(records))
|
||||
if count == 0 {
|
||||
return []byte("[]"), 0, err
|
||||
}
|
||||
// we need to return only list of briefs
|
||||
var result []string
|
||||
for _, rec := range records {
|
||||
result = append(result, rec["brief"].(string))
|
||||
}
|
||||
resultJSON, err := json.Marshal(result)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
//fmt.Printf("Found multiple documents (array of pointers): %+v\n", results)
|
||||
return resultJSON, count, nil
|
||||
}
|
||||
|
||||
func (dbobj dbcon) expireConsentRecords(notifyURL string) error {
|
||||
records, err := dbobj.store.GetExpiring(storage.TblName.Consent, "status", "yes")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, rec := range records {
|
||||
now := int32(time.Now().Unix())
|
||||
// update date, status
|
||||
bdoc := bson.M{}
|
||||
bdoc["when"] = now
|
||||
bdoc["status"] = "expired"
|
||||
userTOKEN := rec["token"].(string)
|
||||
brief := rec["brief"].(string)
|
||||
fmt.Printf("This consent record is expired: %s - %s\n", userTOKEN, brief)
|
||||
if len(userTOKEN) > 0 {
|
||||
fmt.Printf("%s %s\n", userTOKEN, brief)
|
||||
dbobj.store.UpdateRecord2(storage.TblName.Consent, "token", userTOKEN, "brief", brief, &bdoc, nil)
|
||||
notifyConsentChange(notifyURL, brief, "expired", "token", userTOKEN)
|
||||
} else {
|
||||
usercode := rec["who"].(string)
|
||||
dbobj.store.UpdateRecord2(storage.TblName.Consent, "who", usercode, "brief", brief, &bdoc, nil)
|
||||
notifyConsentChange(notifyURL, brief, "expired", rec["mode"].(string), usercode)
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
124
src/lbasis_api.go
Normal file
124
src/lbasis_api.go
Normal file
@@ -0,0 +1,124 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
//"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
func (e mainEnv) createLegalBasis(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
brief := ps.ByName("brief")
|
||||
authResult := e.enforceAdmin(w, r)
|
||||
if authResult == "" {
|
||||
return
|
||||
}
|
||||
brief = normalizeBrief(brief)
|
||||
if isValidBrief(brief) == false {
|
||||
returnError(w, r, "bad brief format", 405, nil, nil)
|
||||
return
|
||||
}
|
||||
records, err := getJSONPostData(r)
|
||||
if err != nil {
|
||||
returnError(w, r, "failed to decode request body", 405, err, nil)
|
||||
return
|
||||
}
|
||||
|
||||
module := ""
|
||||
fulldesc := ""
|
||||
shortdesc := ""
|
||||
basistype := ""
|
||||
requiredmsg := ""
|
||||
usercontrol := false
|
||||
requiredflag := false
|
||||
|
||||
if value, ok := records["module"]; ok {
|
||||
if reflect.TypeOf(value) == reflect.TypeOf("string") {
|
||||
module = value.(string)
|
||||
}
|
||||
}
|
||||
if value, ok := records["fulldesc"]; ok {
|
||||
if reflect.TypeOf(value) == reflect.TypeOf("string") {
|
||||
fulldesc = value.(string)
|
||||
}
|
||||
}
|
||||
if value, ok := records["shortdesc"]; ok {
|
||||
if reflect.TypeOf(value) == reflect.TypeOf("string") {
|
||||
shortdesc = value.(string)
|
||||
}
|
||||
}
|
||||
if value, ok := records["basistype"]; ok {
|
||||
if reflect.TypeOf(value) == reflect.TypeOf("string") {
|
||||
basistype = value.(string)
|
||||
}
|
||||
}
|
||||
basistype = normalizeBasisType(basistype)
|
||||
if value, ok := records["requiredmsg"]; ok {
|
||||
if reflect.TypeOf(value) == reflect.TypeOf("string") {
|
||||
requiredmsg = value.(string)
|
||||
}
|
||||
}
|
||||
if value, ok := records["usercontrol"]; ok {
|
||||
if reflect.TypeOf(value).Kind() == reflect.Bool {
|
||||
usercontrol = value.(bool)
|
||||
}
|
||||
}
|
||||
if value, ok := records["requiredflag"]; ok {
|
||||
if reflect.TypeOf(value).Kind() == reflect.Bool {
|
||||
requiredflag = value.(bool)
|
||||
}
|
||||
}
|
||||
|
||||
e.db.createLegalBasis(brief, module, shortdesc, fulldesc, basistype, requiredmsg, usercontrol, requiredflag)
|
||||
/*
|
||||
notifyURL := e.conf.Notification.NotificationURL
|
||||
if newStatus == true && len(notifyURL) > 0 {
|
||||
// change notificate on new record or if status change
|
||||
if len(userTOKEN) > 0 {
|
||||
notifyConsentChange(notifyURL, brief, status, "token", userTOKEN)
|
||||
} else {
|
||||
notifyConsentChange(notifyURL, brief, status, mode, address)
|
||||
}
|
||||
}
|
||||
*/
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
w.WriteHeader(200)
|
||||
w.Write([]byte(`{"status":"ok"}`))
|
||||
}
|
||||
|
||||
func (e mainEnv) deleteLegalBasis(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
brief := ps.ByName("brief")
|
||||
authResult := e.enforceAdmin(w, r)
|
||||
if authResult == "" {
|
||||
return
|
||||
}
|
||||
brief = normalizeBrief(brief)
|
||||
if isValidBrief(brief) == false {
|
||||
returnError(w, r, "bad brief format", 405, nil, nil)
|
||||
return
|
||||
}
|
||||
e.db.deleteLegalBasis(brief);
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
w.WriteHeader(200)
|
||||
w.Write([]byte(`{"status":"ok"}`))
|
||||
}
|
||||
|
||||
func (e mainEnv) listLegalBasisRecords(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
authResult := e.enforceAdmin(w, r)
|
||||
if authResult == "" {
|
||||
return
|
||||
}
|
||||
resultJSON, numRecords, err := e.db.getLegalBasisRecords()
|
||||
if err != nil {
|
||||
returnError(w, r, "internal error", 405, err, nil)
|
||||
return
|
||||
}
|
||||
fmt.Printf("Total count of rows: %d\n", numRecords)
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
w.WriteHeader(200)
|
||||
str := fmt.Sprintf(`{"status":"ok","total":%d,"rows":%s}`, numRecords, resultJSON)
|
||||
w.Write([]byte(str))
|
||||
}
|
||||
118
src/lbasis_db.go
Normal file
118
src/lbasis_db.go
Normal file
@@ -0,0 +1,118 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/paranoidguy/databunker/src/storage"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
type legalBasis struct {
|
||||
Brief string `json:"brief" structs:"brief"`
|
||||
Status string `json:"status" structs:"status"`
|
||||
Module string `json:"module,omitempty" structs:"module,omitempty"`
|
||||
Shortdesc string `json:"shortdesc,omitempty" structs:"shortdesc,omitempty"`
|
||||
Fulldesc string `json:"fulldesc,omitempty" structs:"fulldesc,omitempty"`
|
||||
Basistype string `json:"basistype,omitempty" structs:"basistype"`
|
||||
Requiredmsg string `json:"requiredmsg,omitempty" structs:"requiredmsg,omitempty"`
|
||||
Usercontrol bool `json:"usercontrol" structs:"usercontrol"`
|
||||
Requiredflag bool `json:"requiredflag" structs:"requiredflag"`
|
||||
Creationtime int32 `json:"creationtime" structs:"creationtime"`
|
||||
}
|
||||
|
||||
func (dbobj dbcon) createLegalBasis(brief string, module string, shortdesc string, fulldesc string, basistype string, requiredmsg string,
|
||||
usercontrol bool, requiredflag bool) (bool, error) {
|
||||
now := int32(time.Now().Unix())
|
||||
bdoc := bson.M{}
|
||||
bdoc["basistype"] = basistype
|
||||
if len(module) > 0 {
|
||||
bdoc["module"] = module
|
||||
}
|
||||
if len(shortdesc) > 0 {
|
||||
bdoc["shortdesc"] = shortdesc
|
||||
}
|
||||
if len(fulldesc) > 0 {
|
||||
bdoc["fulldesc"] = fulldesc
|
||||
}
|
||||
if len(requiredmsg) > 0 {
|
||||
bdoc["requiredmsg"] = requiredmsg
|
||||
}
|
||||
bdoc["status"] = "active";
|
||||
bdoc["usercontrol"] = usercontrol
|
||||
bdoc["requiredflag"] = requiredflag
|
||||
raw, err := dbobj.store.GetRecord(storage.TblName.Legalbasis, "brief", brief)
|
||||
if err != nil {
|
||||
fmt.Printf("error to find:%s", err)
|
||||
return false, err
|
||||
}
|
||||
if raw != nil {
|
||||
if basistype != raw["basistype"].(string) {
|
||||
// check if this legitbasis is used to change it's structure
|
||||
} else {
|
||||
dbobj.store.UpdateRecord(storage.TblName.Legalbasis, "brief", brief, &bdoc)
|
||||
return true, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
bdoc["brief"] = brief
|
||||
bdoc["creationtime"] = now
|
||||
_, err = dbobj.store.CreateRecord(storage.TblName.Legalbasis, &bdoc)
|
||||
if err != nil {
|
||||
fmt.Printf("error to insert record: %s\n", err)
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (dbobj dbcon) deleteLegalBasis(brief string) (bool, error) {
|
||||
// look up for user with this legal basis
|
||||
count, err := dbobj.store.CountRecords(storage.TblName.Agreements, "brief", brief)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if count == 0 {
|
||||
// we can safely remove this record
|
||||
dbobj.store.DeleteRecord(storage.TblName.Legalbasis, "brief", brief)
|
||||
return true, nil
|
||||
}
|
||||
// change status to revoked for users
|
||||
bdoc := bson.M{}
|
||||
now := int32(time.Now().Unix())
|
||||
bdoc["when"] = now
|
||||
bdoc["status"] = "revoked"
|
||||
dbobj.store.UpdateRecord2(storage.TblName.Agreements, "brief", brief, "status", "yes", &bdoc, nil)
|
||||
bdoc2 := bson.M{}
|
||||
bdoc2["status"] = "deleted"
|
||||
dbobj.store.UpdateRecord(storage.TblName.Legalbasis, "brief", brief, &bdoc2)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (dbobj dbcon) getLegalBasisRecords() ([]byte, int, error) {
|
||||
records, err := dbobj.store.GetList0(storage.TblName.Legalbasis, 0, 0, "")
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
count := len(records)
|
||||
if count == 0 {
|
||||
return []byte("[]"), 0, err
|
||||
}
|
||||
resultJSON, err := json.Marshal(records)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
//fmt.Printf("Found multiple documents (array of pointers): %+v\n", results)
|
||||
return resultJSON, count, nil
|
||||
}
|
||||
|
||||
func (dbobj dbcon) checkLegalBasis(brief string) (bool, error) {
|
||||
count, err := dbobj.store.CountRecords(storage.TblName.Legalbasis, "brief", brief)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if count == 0 {
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
161
src/pactivities_api.go
Normal file
161
src/pactivities_api.go
Normal file
@@ -0,0 +1,161 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
//"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
func (e mainEnv) pactivityCreate(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
activity := ps.ByName("activity")
|
||||
authResult := e.enforceAdmin(w, r)
|
||||
if authResult == "" {
|
||||
return
|
||||
}
|
||||
activity = normalizeBrief(activity)
|
||||
if isValidBrief(activity) == false {
|
||||
returnError(w, r, "bad activity format", 405, nil, nil)
|
||||
return
|
||||
}
|
||||
records, err := getJSONPostData(r)
|
||||
if err != nil {
|
||||
returnError(w, r, "failed to decode request body", 405, err, nil)
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
w.WriteHeader(200)
|
||||
w.Write([]byte(`{"status":"ok"}`))
|
||||
}()
|
||||
|
||||
title := ""
|
||||
script := ""
|
||||
fulldesc := ""
|
||||
legalbasis := ""
|
||||
applicableto := ""
|
||||
if value, ok := records["title"]; ok {
|
||||
if reflect.TypeOf(value) == reflect.TypeOf("string") {
|
||||
title = value.(string)
|
||||
}
|
||||
}
|
||||
if len(title) == 0 {
|
||||
title = activity
|
||||
}
|
||||
if value, ok := records["script"]; ok {
|
||||
if reflect.TypeOf(value) == reflect.TypeOf("string") {
|
||||
script = value.(string)
|
||||
}
|
||||
}
|
||||
if value, ok := records["fulldesc"]; ok {
|
||||
if reflect.TypeOf(value) == reflect.TypeOf("string") {
|
||||
fulldesc = value.(string)
|
||||
}
|
||||
}
|
||||
if value, ok := records["applicableto"]; ok {
|
||||
if reflect.TypeOf(value) == reflect.TypeOf("string") {
|
||||
applicableto = value.(string)
|
||||
}
|
||||
}
|
||||
e.db.createProcessingActivity(activity, title, script, fulldesc, legalbasis, applicableto)
|
||||
}
|
||||
|
||||
func (e mainEnv) pactivityDelete(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
activity := ps.ByName("activity")
|
||||
authResult := e.enforceAdmin(w, r)
|
||||
if authResult == "" {
|
||||
return
|
||||
}
|
||||
activity = normalizeBrief(activity)
|
||||
if isValidBrief(activity) == false {
|
||||
returnError(w, r, "bad activity format", 405, nil, nil)
|
||||
return
|
||||
}
|
||||
e.db.deleteProcessingActivity(activity)
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
w.WriteHeader(200)
|
||||
w.Write([]byte(`{"status":"ok"}`))
|
||||
}
|
||||
|
||||
func (e mainEnv) pactivityLink(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
activity := ps.ByName("activity")
|
||||
brief := ps.ByName("brief")
|
||||
authResult := e.enforceAdmin(w, r)
|
||||
if authResult == "" {
|
||||
return
|
||||
}
|
||||
activity = normalizeBrief(activity)
|
||||
if isValidBrief(activity) == false {
|
||||
returnError(w, r, "bad activity format", 405, nil, nil)
|
||||
return
|
||||
}
|
||||
brief = normalizeBrief(brief)
|
||||
if isValidBrief(brief) == false {
|
||||
returnError(w, r, "bad brief format", 405, nil, nil)
|
||||
return
|
||||
}
|
||||
exists, err := e.db.checkLegalBasis(brief)
|
||||
if err != nil {
|
||||
returnError(w, r, "internal error", 405, nil, nil)
|
||||
return
|
||||
}
|
||||
if exists == false {
|
||||
returnError(w, r, "not found", 405, nil, nil)
|
||||
return
|
||||
}
|
||||
_, err = e.db.linkProcessingActivity(activity, brief)
|
||||
if err != nil {
|
||||
returnError(w, r, "internal error", 405, err, nil)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
w.WriteHeader(200)
|
||||
w.Write([]byte(`{"status":"ok"}`))
|
||||
}
|
||||
|
||||
func (e mainEnv) pactivityUnlink(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
activity := ps.ByName("activity")
|
||||
brief := ps.ByName("brief")
|
||||
authResult := e.enforceAdmin(w, r)
|
||||
if authResult == "" {
|
||||
return
|
||||
}
|
||||
activity = normalizeBrief(activity)
|
||||
if isValidBrief(activity) == false {
|
||||
returnError(w, r, "bad activity format", 405, nil, nil)
|
||||
return
|
||||
}
|
||||
brief = normalizeBrief(brief)
|
||||
if isValidBrief(brief) == false {
|
||||
returnError(w, r, "bad brief format", 405, nil, nil)
|
||||
return
|
||||
}
|
||||
_, err := e.db.unlinkProcessingActivity(activity, brief)
|
||||
if err != nil {
|
||||
returnError(w, r, "internal error", 405, err, nil)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
w.WriteHeader(200)
|
||||
w.Write([]byte(`{"status":"ok"}`))
|
||||
}
|
||||
|
||||
func (e mainEnv) pactivityList(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
authResult := e.enforceAdmin(w, r)
|
||||
if authResult == "" {
|
||||
return
|
||||
}
|
||||
resultJSON, numRecords, err := e.db.listProcessingActivities()
|
||||
if err != nil {
|
||||
returnError(w, r, "internal error", 405, err, nil)
|
||||
return
|
||||
}
|
||||
fmt.Printf("Total count of rows: %d\n", numRecords)
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
w.WriteHeader(200)
|
||||
str := fmt.Sprintf(`{"status":"ok","total":%d,"rows":%s}`, numRecords, resultJSON)
|
||||
w.Write([]byte(str))
|
||||
}
|
||||
170
src/pactivities_db.go
Normal file
170
src/pactivities_db.go
Normal file
@@ -0,0 +1,170 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/paranoidguy/databunker/src/storage"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
type processingActivity struct {
|
||||
Activity string `json:"activity" structs:"activity"`
|
||||
Title string `json:"title" structs:"title"`
|
||||
Script string `json:"script,omitempty" structs:"script,omitempty"`
|
||||
Fulldesc string `json:"fulldesc,omitempty" structs:"fulldesc,omitempty"`
|
||||
Legalbasis string `json:"legalbasis,omitempty" structs:"legalbasis,omitempty"`
|
||||
Applicableto string `json:"applicableto,omitempty" structs:"applicableto,omitempty"`
|
||||
Creationtime int32 `json:"creationtime" structs:"creationtime"`
|
||||
}
|
||||
|
||||
func (dbobj dbcon) createProcessingActivity(activity string, title string, script string, fulldesc string, legalbasis string, applicableto string) (bool, error) {
|
||||
now := int32(time.Now().Unix())
|
||||
bdoc := bson.M{}
|
||||
bdoc["creationtime"] = now
|
||||
if len(activity) > 0 {
|
||||
bdoc["activity"] = activity
|
||||
}
|
||||
if len(title) > 0 {
|
||||
bdoc["title"] = title
|
||||
}
|
||||
if len(script) > 0 {
|
||||
bdoc["script"] = script
|
||||
}
|
||||
if len(fulldesc) > 0 {
|
||||
bdoc["fulldesc"] = fulldesc
|
||||
}
|
||||
if len(legalbasis) > 0 {
|
||||
bdoc["legalbasis"] = legalbasis
|
||||
}
|
||||
if len(applicableto) > 0 {
|
||||
bdoc["applicableto"] = applicableto
|
||||
}
|
||||
raw, err := dbobj.store.GetRecord(storage.TblName.Processingactivities, "activity", activity)
|
||||
if err != nil {
|
||||
fmt.Printf("error to find:%s", err)
|
||||
return false, err
|
||||
}
|
||||
if raw != nil {
|
||||
_, err = dbobj.store.UpdateRecord(storage.TblName.Processingactivities, "activity", activity, &bdoc)
|
||||
return false, err
|
||||
}
|
||||
_, err = dbobj.store.CreateRecord(storage.TblName.Processingactivities, &bdoc)
|
||||
if err != nil {
|
||||
fmt.Printf("error to insert record: %s\n", err)
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (dbobj dbcon) deleteProcessingActivity(activity string) (bool, error) {
|
||||
dbobj.store.DeleteRecord(storage.TblName.Processingactivities, "activity", activity)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (dbobj dbcon) linkProcessingActivity(activity string, brief string) (bool, error) {
|
||||
raw, err := dbobj.store.GetRecord(storage.TblName.Processingactivities, "activity", activity)
|
||||
if err != nil {
|
||||
fmt.Printf("error to find:%s", err)
|
||||
return false, err
|
||||
}
|
||||
if raw == nil {
|
||||
return false, errors.New("not found")
|
||||
}
|
||||
legalbasis := ""
|
||||
if value, ok := raw["legalbasis"]; ok {
|
||||
if reflect.TypeOf(value) == reflect.TypeOf("string") {
|
||||
legalbasis = value.(string)
|
||||
}
|
||||
}
|
||||
briefs := strings.Split(legalbasis, ",")
|
||||
if contains(briefs, brief) == true {
|
||||
// nothing to do here
|
||||
return false, nil
|
||||
}
|
||||
if len(legalbasis) > 0 {
|
||||
legalbasis = legalbasis + "," + brief
|
||||
} else {
|
||||
legalbasis = brief
|
||||
}
|
||||
bdoc := bson.M{}
|
||||
bdoc["legalbasis"] = legalbasis
|
||||
_, err = dbobj.store.UpdateRecord(storage.TblName.Processingactivities, "activity", activity, &bdoc)
|
||||
return true, err
|
||||
}
|
||||
|
||||
func (dbobj dbcon) unlinkProcessingActivity(activity string, brief string) (bool, error) {
|
||||
raw, err := dbobj.store.GetRecord(storage.TblName.Processingactivities, "activity", activity)
|
||||
if err != nil {
|
||||
fmt.Printf("error to find:%s", err)
|
||||
return false, err
|
||||
}
|
||||
if raw == nil {
|
||||
return false, errors.New("not found")
|
||||
}
|
||||
legalbasis := ""
|
||||
if val, ok := raw["legalbasis"]; ok {
|
||||
if reflect.TypeOf(val) == reflect.TypeOf("string") {
|
||||
legalbasis = val.(string)
|
||||
}
|
||||
}
|
||||
briefs := strings.Split(legalbasis, ",")
|
||||
if contains(briefs, brief) == false {
|
||||
// nothing to do here
|
||||
return false, nil
|
||||
}
|
||||
legalbasis = ""
|
||||
for _, value := range briefs {
|
||||
if value != brief {
|
||||
if len(legalbasis) > 0 {
|
||||
legalbasis = legalbasis + "," + value
|
||||
} else {
|
||||
legalbasis = value
|
||||
}
|
||||
}
|
||||
}
|
||||
bdoc := bson.M{}
|
||||
bdoc["legalbasis"] = legalbasis
|
||||
_, err = dbobj.store.UpdateRecord(storage.TblName.Processingactivities, "activity", activity, &bdoc)
|
||||
return true, err
|
||||
}
|
||||
|
||||
func (dbobj dbcon) listProcessingActivities() ([]byte, int, error) {
|
||||
set := make(map[string]interface{})
|
||||
records0, err := dbobj.store.GetList0(storage.TblName.Legalbasis, 0, 0, "")
|
||||
for _, val := range records0 {
|
||||
set[val["brief"].(string)] = val
|
||||
}
|
||||
records, err := dbobj.store.GetList0(storage.TblName.Processingactivities, 0, 0, "")
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
count := len(records)
|
||||
if count == 0 {
|
||||
return []byte("[]"), 0, err
|
||||
}
|
||||
var results []interface{}
|
||||
for _, record := range records {
|
||||
briefs := strings.Split(record["legalbasis"].(string), ",")
|
||||
var results0 []interface{}
|
||||
if len(briefs) > 0 {
|
||||
for _, brief := range briefs {
|
||||
if value, ok := set[brief]; ok {
|
||||
results0 = append(results0, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
record["briefs"] = results0
|
||||
results = append(results, record)
|
||||
}
|
||||
resultJSON, err := json.Marshal(results)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
//fmt.Printf("Found multiple documents (array of pointers): %+v\n", results)
|
||||
return resultJSON, count, nil
|
||||
}
|
||||
@@ -142,7 +142,7 @@ func (e mainEnv) getUserRequest(w http.ResponseWriter, r *http.Request, ps httpr
|
||||
if len(appName) > 0 {
|
||||
resultJSON, err = e.db.getUserApp(userTOKEN, appName)
|
||||
} else if len(brief) > 0 {
|
||||
resultJSON, err = e.db.viewConsentRecord(userTOKEN, brief)
|
||||
resultJSON, err = e.db.viewAgreementRecord(userTOKEN, brief)
|
||||
} else {
|
||||
resultJSON, err = e.db.getUser(userTOKEN)
|
||||
}
|
||||
@@ -251,11 +251,11 @@ func (e mainEnv) approveUserRequest(w http.ResponseWriter, r *http.Request, ps h
|
||||
returnError(w, r, "internal error", 405, err, event)
|
||||
return
|
||||
}
|
||||
} else if action == "consent-withdraw" {
|
||||
} else if action == "agreement-withdraw" {
|
||||
brief := requestInfo["brief"].(string)
|
||||
mode := "token"
|
||||
lastmodifiedby := "admin"
|
||||
e.db.withdrawConsentRecord(userTOKEN, brief, mode, userTOKEN, lastmodifiedby)
|
||||
e.db.withdrawAgreement(userTOKEN, brief, mode, userTOKEN, lastmodifiedby)
|
||||
}
|
||||
e.db.updateRequestStatus(request, "approved", "")
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
|
||||
@@ -30,10 +30,12 @@ type listTbls struct {
|
||||
Users Tbl
|
||||
Audit Tbl
|
||||
Xtokens Tbl
|
||||
Consent Tbl
|
||||
Sessions Tbl
|
||||
Requests Tbl
|
||||
Legalbasis Tbl
|
||||
Agreements Tbl
|
||||
Sharedrecords Tbl
|
||||
Processingactivities Tbl
|
||||
}
|
||||
|
||||
// TblName is enum of tables
|
||||
@@ -41,10 +43,12 @@ var TblName = &listTbls{
|
||||
Users: 0,
|
||||
Audit: 1,
|
||||
Xtokens: 2,
|
||||
Consent: 3,
|
||||
Sessions: 4,
|
||||
Requests: 5,
|
||||
Sharedrecords: 6,
|
||||
Sessions: 3,
|
||||
Requests: 4,
|
||||
Legalbasis: 5,
|
||||
Agreements: 6,
|
||||
Sharedrecords: 7,
|
||||
Processingactivities: 8,
|
||||
}
|
||||
|
||||
// DBStorage struct is used to store database object
|
||||
@@ -161,10 +165,12 @@ func InitDB(filepath *string) (DBStorage, error){
|
||||
initUsers(dbobj.db)
|
||||
initXTokens(dbobj.db)
|
||||
initAudit(dbobj.db)
|
||||
initConsent(dbobj.db)
|
||||
initSessions(dbobj.db)
|
||||
initRequests(dbobj.db)
|
||||
initSharedRecords(dbobj.db)
|
||||
initProcessingactivities(dbobj.db)
|
||||
initLegalbasis(dbobj.db)
|
||||
initAgreements(dbobj.db)
|
||||
return dbobj, nil
|
||||
}
|
||||
|
||||
@@ -303,16 +309,20 @@ func getTable(t Tbl) string {
|
||||
return "users"
|
||||
case TblName.Audit:
|
||||
return "audit"
|
||||
case TblName.Consent:
|
||||
return "consent"
|
||||
case TblName.Xtokens:
|
||||
return "xtokens"
|
||||
case TblName.Sessions:
|
||||
return "sessions"
|
||||
case TblName.Requests:
|
||||
return "requests"
|
||||
case TblName.Legalbasis:
|
||||
return "legalbasis"
|
||||
case TblName.Agreements:
|
||||
return "agreements"
|
||||
case TblName.Sharedrecords:
|
||||
return "sharedrecords"
|
||||
case TblName.Processingactivities:
|
||||
return "processingactivities"
|
||||
}
|
||||
return "users"
|
||||
}
|
||||
@@ -530,6 +540,8 @@ func (dbobj DBStorage) getRecordInTableDo(q string, values []interface{}) (bson.
|
||||
recBson[colName] = int32(columns[i].(int64))
|
||||
case int32:
|
||||
recBson[colName] = int32(columns[i].(int32))
|
||||
case bool:
|
||||
recBson[colName] = columns[i].(bool)
|
||||
case nil:
|
||||
//fmt.Printf("is nil, not interesting\n")
|
||||
default:
|
||||
@@ -728,6 +740,28 @@ func (dbobj DBStorage) GetUniqueList(t Tbl, keyName string) ([]bson.M, error) {
|
||||
return dbobj.getListDo(q, values)
|
||||
}
|
||||
|
||||
// GetList is used to return list of rows. It can be used to return values using pager.
|
||||
func (dbobj DBStorage) GetList0(t Tbl, start int32, limit int32, orderField string) ([]bson.M, error) {
|
||||
table := getTable(t)
|
||||
if limit > 100 {
|
||||
limit = 100
|
||||
}
|
||||
|
||||
q := "select * from " + table
|
||||
if len(orderField) > 0 {
|
||||
q = q + " ORDER BY " + escapeName(orderField) + " DESC"
|
||||
}
|
||||
if start > 0 {
|
||||
q = q + " LIMIT " + strconv.FormatInt(int64(limit), 10) +
|
||||
" OFFSET " + strconv.FormatInt(int64(start), 10)
|
||||
} else if limit > 0 {
|
||||
q = q + " LIMIT " + strconv.FormatInt(int64(limit), 10)
|
||||
}
|
||||
fmt.Printf("q: %s\n", q)
|
||||
values := make([]interface{}, 0)
|
||||
return dbobj.getListDo(q, values)
|
||||
}
|
||||
|
||||
// GetList is used to return list of rows. It can be used to return values using pager.
|
||||
func (dbobj DBStorage) GetList(t Tbl, keyName string, keyValue string, start int32, limit int32, orderField string) ([]bson.M, error) {
|
||||
table := getTable(t)
|
||||
@@ -806,6 +840,8 @@ func (dbobj DBStorage) getListDo(q string, values []interface{}) ([]bson.M, erro
|
||||
recBson[colName] = string(columns[i].([]uint8))
|
||||
case int64:
|
||||
recBson[colName] = int32(columns[i].(int64))
|
||||
case bool:
|
||||
recBson[colName] = columns[i].(bool)
|
||||
case nil:
|
||||
//fmt.Printf("is nil, not interesting\n")
|
||||
default:
|
||||
@@ -970,24 +1006,51 @@ func initRequests(db *sql.DB) error {
|
||||
return execQueries(db, queries)
|
||||
}
|
||||
|
||||
func initConsent(db *sql.DB) error {
|
||||
queries := []string{`CREATE TABLE IF NOT EXISTS consent (
|
||||
func initProcessingactivities(db *sql.DB) error {
|
||||
queries := []string{`CREATE TABLE IF NOT EXISTS processingactivities (
|
||||
activity STRING,
|
||||
title STRING,
|
||||
script STRING,
|
||||
fulldesc STRING,
|
||||
legalbasis STRING,
|
||||
applicableto STRING,
|
||||
creationtime int);`,
|
||||
`CREATE INDEX processingactivities_activity ON processingactivities (activity);`}
|
||||
return execQueries(db, queries)
|
||||
}
|
||||
|
||||
func initLegalbasis(db *sql.DB) error {
|
||||
queries := []string{`CREATE TABLE IF NOT EXISTS legalbasis (
|
||||
brief STRING,
|
||||
status STRING,
|
||||
module STRING,
|
||||
shortdesc STRING,
|
||||
fulldesc STRING,
|
||||
basistype STRING,
|
||||
requiredmsg STRING,
|
||||
usercontrol BOOLEAN,
|
||||
requiredflag BOOLEAN,
|
||||
creationtime int);`,
|
||||
`CREATE INDEX legalbasis_brief ON legalbasis (brief);`}
|
||||
return execQueries(db, queries)
|
||||
}
|
||||
|
||||
func initAgreements(db *sql.DB) error {
|
||||
queries := []string{`CREATE TABLE IF NOT EXISTS agreements (
|
||||
who STRING,
|
||||
mode STRING,
|
||||
token STRING,
|
||||
brief STRING,
|
||||
status STRING,
|
||||
message STRING,
|
||||
freetext STRING,
|
||||
lawfulbasis STRING,
|
||||
consentmethod STRING,
|
||||
referencecode STRING,
|
||||
lastmodifiedby STRING,
|
||||
agreementmethod STRING,
|
||||
creationtime int,
|
||||
starttime int,
|
||||
endtime int,
|
||||
` + "`when` int);",
|
||||
`CREATE INDEX consent_token ON consent (token);`}
|
||||
`CREATE INDEX agreements_token ON agreements (token);`,
|
||||
`CREATE INDEX agreements_brief ON agreements (brief);`}
|
||||
return execQueries(db, queries)
|
||||
}
|
||||
|
||||
|
||||
@@ -74,24 +74,24 @@ func (e mainEnv) userNew(w http.ResponseWriter, r *http.Request, ps httprouter.P
|
||||
return
|
||||
}
|
||||
if len(parsedData.emailIdx) > 0 {
|
||||
e.db.linkConsentRecords(userTOKEN, "email", parsedData.emailIdx)
|
||||
e.db.linkAgreementRecords(userTOKEN, "email", parsedData.emailIdx)
|
||||
}
|
||||
if len(parsedData.phoneIdx) > 0 {
|
||||
e.db.linkConsentRecords(userTOKEN, "phone", parsedData.phoneIdx)
|
||||
e.db.linkAgreementRecords(userTOKEN, "phone", parsedData.phoneIdx)
|
||||
}
|
||||
if len(parsedData.emailIdx) > 0 && len(parsedData.phoneIdx) > 0 {
|
||||
// delete duplicate consent records for user
|
||||
records, _ := e.db.store.GetList(storage.TblName.Consent, "who", parsedData.emailIdx, 0, 0, "")
|
||||
records, _ := e.db.store.GetList(storage.TblName.Agreements, "who", parsedData.emailIdx, 0, 0, "")
|
||||
var briefCodes []string
|
||||
for _, val := range records {
|
||||
//fmt.Printf("adding brief code: %s\n", val["brief"].(string))
|
||||
briefCodes = append(briefCodes, val["brief"].(string))
|
||||
}
|
||||
records, _ = e.db.store.GetList(storage.TblName.Consent, "who", parsedData.phoneIdx, 0, 0, "")
|
||||
records, _ = e.db.store.GetList(storage.TblName.Agreements, "who", parsedData.phoneIdx, 0, 0, "")
|
||||
for _, val := range records {
|
||||
//fmt.Printf("XXX checking brief code for duplicates: %s\n", val["brief"].(string))
|
||||
if contains(briefCodes, val["brief"].(string)) == true {
|
||||
e.db.store.DeleteRecord2(storage.TblName.Consent, "token", userTOKEN, "who", parsedData.phoneIdx)
|
||||
e.db.store.DeleteRecord2(storage.TblName.Agreements, "token", userTOKEN, "who", parsedData.phoneIdx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
25
src/utils.go
25
src/utils.go
@@ -29,6 +29,7 @@ var (
|
||||
regexExpiration = regexp.MustCompile("^([0-9]+)([mhds])?$")
|
||||
regexHex = regexp.MustCompile("^[a-zA-F0-9]+$")
|
||||
consentYesStatuses = []string{"y", "yes", "accept", "agree", "approve", "given", "true", "good"}
|
||||
basisTypes = []string{"consent", "contract", "legitimate-interest", "vital-interest", "legal-requirement", "public-interest"}
|
||||
)
|
||||
|
||||
// Consideration why collection of meta data patch was postpone:
|
||||
@@ -69,6 +70,14 @@ func normalizeConsentStatus(status string) string {
|
||||
return "no"
|
||||
}
|
||||
|
||||
func normalizeBasisType(status string) string {
|
||||
status = strings.ToLower(status)
|
||||
if contains(basisTypes, status) {
|
||||
return status
|
||||
}
|
||||
return "consent"
|
||||
}
|
||||
|
||||
func normalizeBrief(brief string) string {
|
||||
return strings.ToLower(brief)
|
||||
}
|
||||
@@ -347,6 +356,22 @@ func (e mainEnv) enforceAuth(w http.ResponseWriter, r *http.Request, event *audi
|
||||
return ""
|
||||
}
|
||||
|
||||
func (e mainEnv) enforceAdmin(w http.ResponseWriter, r *http.Request) string {
|
||||
if token, ok := r.Header["X-Bunker-Token"]; ok {
|
||||
authResult, err := e.db.checkUserAuthXToken(token[0])
|
||||
//fmt.Printf("error in auth? error %s - %s\n", err, token[0])
|
||||
if err == nil {
|
||||
if len(authResult.ttype) > 0 && authResult.ttype != "login" {
|
||||
return authResult.ttype
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Printf("403 Access denied\n")
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
w.Write([]byte("Access denied"))
|
||||
return ""
|
||||
}
|
||||
|
||||
func enforceUUID(w http.ResponseWriter, uuidCode string, event *auditEvent) bool {
|
||||
if isValidUUID(uuidCode) == false {
|
||||
fmt.Printf("405 bad uuid in : %s\n", uuidCode)
|
||||
|
||||
Reference in New Issue
Block a user