mirror of
				https://github.com/optim-enterprises-bv/databunker.git
				synced 2025-10-30 01:22:28 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			492 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			492 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package main
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"log"
 | |
| 	"net/http"
 | |
| 	"reflect"
 | |
| 
 | |
| 	"github.com/julienschmidt/httprouter"
 | |
| 	//"go.mongodb.org/mongo-driver/bson"
 | |
| )
 | |
| 
 | |
| func (e mainEnv) agreementAccept(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
 | |
| 	identity := ps.ByName("identity")
 | |
| 	brief := ps.ByName("brief")
 | |
| 	mode := ps.ByName("mode")
 | |
| 	event := audit("accept agreement by "+brief, identity, mode, identity)
 | |
| 	defer func() { event.submit(e.db, e.conf) }()
 | |
| 
 | |
| 	if validateMode(mode) == false {
 | |
| 		returnError(w, r, "bad mode", 405, nil, event)
 | |
| 		return
 | |
| 	}
 | |
| 	brief = normalizeBrief(brief)
 | |
| 	if isValidBrief(brief) == false {
 | |
| 		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, err, event)
 | |
| 		return
 | |
| 	}
 | |
| 	if exists == false {
 | |
| 		returnError(w, r, "not found", 404, nil, event)
 | |
| 		return
 | |
| 	}
 | |
| 	userTOKEN := ""
 | |
| 	if mode == "token" {
 | |
| 		if enforceUUID(w, identity, event) == false {
 | |
| 			return
 | |
| 		}
 | |
| 		userBson, err := e.db.lookupUserRecord(identity)
 | |
| 		if err != nil || userBson == nil {
 | |
| 			returnError(w, r, "internal error", 405, err, event)
 | |
| 			return
 | |
| 		}
 | |
| 		if e.enforceAuth(w, r, event) == "" {
 | |
| 			return
 | |
| 		}
 | |
| 		userTOKEN = identity
 | |
| 	} else {
 | |
| 		userBson, err := e.db.lookupUserRecordByIndex(mode, identity, e.conf)
 | |
| 		if err != nil {
 | |
| 			returnError(w, r, "internal error", 405, err, event)
 | |
| 			return
 | |
| 		}
 | |
| 		if userBson != nil {
 | |
| 			userTOKEN = userBson["token"].(string)
 | |
| 			event.Record = userTOKEN
 | |
| 		} else {
 | |
| 			if mode == "login" {
 | |
| 				returnError(w, r, "internal error", 405, nil, event)
 | |
| 				return
 | |
| 			}
 | |
| 			// else user not found - we allow to save consent for unlinked users!
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	records, err := getJSONPostMap(r)
 | |
| 	if err != nil {
 | |
| 		returnError(w, r, "failed to decode request body", 405, err, event)
 | |
| 		return
 | |
| 	}
 | |
| 	starttime := int32(0)
 | |
| 	expiration := int32(0)
 | |
| 	referencecode := getStringValue(records["referencecode"])
 | |
| 	lastmodifiedby := getStringValue(records["lastmodifiedby"])
 | |
| 	agreementmethod := getStringValue(records["agreementmethod"])
 | |
| 	status := getStringValue(records["status"])
 | |
| 	if len(status) == 0 {
 | |
| 		status = "yes"
 | |
| 	} else {
 | |
| 		status = normalizeConsentStatus(status)
 | |
| 	}
 | |
| 	if value, ok := records["expiration"]; ok {
 | |
| 		switch records["expiration"].(type) {
 | |
| 		case string:
 | |
| 			expiration, _ = parseExpiration(value.(string))
 | |
| 		case float64:
 | |
| 			expiration = int32(value.(float64))
 | |
| 		}
 | |
| 	}
 | |
| 	if value, ok := records["starttime"]; ok {
 | |
| 		switch records["starttime"].(type) {
 | |
| 		case string:
 | |
| 			starttime, _ = parseExpiration(value.(string))
 | |
| 		case float64:
 | |
| 			starttime = int32(value.(float64))
 | |
| 		}
 | |
| 	}
 | |
| 	switch mode {
 | |
| 	case "email":
 | |
| 		identity = normalizeEmail(identity)
 | |
| 	case "phone":
 | |
| 		identity = normalizePhone(identity, e.conf.Sms.DefaultCountry)
 | |
| 	}
 | |
| 	log.Printf("Processing agreement, status: %s\n", status)
 | |
| 	e.db.acceptAgreement(userTOKEN, mode, identity, 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
 | |
| 			if len(userTOKEN) > 0 {
 | |
| 				notifyConsentChange(notifyURL, brief, status, "token", userTOKEN)
 | |
| 			} else {
 | |
| 				notifyConsentChange(notifyURL, brief, status, mode, identity)
 | |
| 			}
 | |
| 		}
 | |
| 	*/
 | |
| 	w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | |
| 	w.WriteHeader(200)
 | |
| 	w.Write([]byte(`{"status":"ok"}`))
 | |
| }
 | |
| 
 | |
| func (e mainEnv) agreementWithdraw(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
 | |
| 	identity := ps.ByName("identity")
 | |
| 	brief := ps.ByName("brief")
 | |
| 	mode := ps.ByName("mode")
 | |
| 	event := audit("withdraw agreement by "+brief, identity, mode, identity)
 | |
| 	defer func() { event.submit(e.db, e.conf) }()
 | |
| 
 | |
| 	if validateMode(mode) == false {
 | |
| 		returnError(w, r, "bad mode", 405, nil, event)
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	brief = normalizeBrief(brief)
 | |
| 	if isValidBrief(brief) == false {
 | |
| 		returnError(w, r, "bad brief format", 405, nil, event)
 | |
| 		return
 | |
| 	}
 | |
| 	lbasis, err := e.db.getLegalBasis(brief)
 | |
| 	if err != nil {
 | |
| 		returnError(w, r, "internal error", 405, err, event)
 | |
| 		return
 | |
| 	}
 | |
| 	if lbasis == nil {
 | |
| 		returnError(w, r, "not  found", 405, nil, event)
 | |
| 		return
 | |
| 	}
 | |
| 	userTOKEN := ""
 | |
| 	authResult := ""
 | |
| 	if mode == "token" {
 | |
| 		if enforceUUID(w, identity, event) == false {
 | |
| 			return
 | |
| 		}
 | |
| 		userBson, _ := e.db.lookupUserRecord(identity)
 | |
| 		if userBson == nil {
 | |
| 			returnError(w, r, "internal error", 405, nil, event)
 | |
| 			return
 | |
| 		}
 | |
| 		authResult = e.enforceAuth(w, r, event)
 | |
| 		if authResult == "" {
 | |
| 			return
 | |
| 		}
 | |
| 		userTOKEN = identity
 | |
| 	} else {
 | |
| 		// TODO: decode url in code!
 | |
| 		userBson, _ := e.db.lookupUserRecordByIndex(mode, identity, e.conf)
 | |
| 		if userBson != nil {
 | |
| 			userTOKEN = userBson["token"].(string)
 | |
| 			event.Record = userTOKEN
 | |
| 		} else {
 | |
| 			if mode == "login" {
 | |
| 				returnError(w, r, "internal error", 405, nil, event)
 | |
| 				return
 | |
| 			}
 | |
| 			// else user not found - we allow to save consent for unlinked users!
 | |
| 		}
 | |
| 	}
 | |
| 	records, err := getJSONPostMap(r)
 | |
| 	if err != nil {
 | |
| 		returnError(w, r, "failed to decode request body", 405, err, event)
 | |
| 		return
 | |
| 	}
 | |
| 	lastmodifiedby := getStringValue(records["lastmodifiedby"])
 | |
| 	selfService := false
 | |
| 	if value, ok := lbasis["usercontrol"]; ok {
 | |
| 		if reflect.TypeOf(value).Kind() == reflect.Bool {
 | |
| 			selfService = value.(bool)
 | |
| 		} else {
 | |
| 			num := value.(int32)
 | |
| 			if num > 0 {
 | |
| 				selfService = true
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	if selfService == false {
 | |
| 		// user can change consent only for briefs defined in self-service
 | |
| 		if len(authResult) == 0 {
 | |
| 			if e.enforceAdmin(w, r) == "" {
 | |
| 				return
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if authResult == "login" && selfService == false {
 | |
| 		rtoken, rstatus, err := e.db.saveUserRequest("agreement-withdraw", userTOKEN, "", brief, nil, e.conf)
 | |
| 		if err != nil {
 | |
| 			returnError(w, r, "internal error", 405, err, event)
 | |
| 			return
 | |
| 		}
 | |
| 		w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | |
| 		w.WriteHeader(200)
 | |
| 		fmt.Fprintf(w, `{"status":"ok","result":"%s","rtoken":"%s"}`, rstatus, rtoken)
 | |
| 		return
 | |
| 	}
 | |
| 	switch mode {
 | |
| 	case "email":
 | |
| 		identity = normalizeEmail(identity)
 | |
| 	case "phone":
 | |
| 		identity = normalizePhone(identity, e.conf.Sms.DefaultCountry)
 | |
| 	}
 | |
| 	e.db.withdrawAgreement(userTOKEN, brief, mode, identity, lastmodifiedby)
 | |
| 	w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | |
| 	w.WriteHeader(200)
 | |
| 	w.Write([]byte(`{"status":"ok"}`))
 | |
| 	notifyURL := e.conf.Notification.NotificationURL
 | |
| 	if len(userTOKEN) > 0 {
 | |
| 		notifyConsentChange(notifyURL, brief, "no", "token", userTOKEN)
 | |
| 	} else {
 | |
| 		notifyConsentChange(notifyURL, brief, "no", mode, identity)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (e mainEnv) agreementRevokeAll(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
 | |
| 	brief := ps.ByName("brief")
 | |
| 	authResult := e.enforceAdmin(w, r)
 | |
| 	if authResult == "" {
 | |
| 		return
 | |
| 	}
 | |
| 	if e.enforceAdmin(w, r) == "" {
 | |
| 		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
 | |
| 	}
 | |
| 	e.db.revokeLegalBasis(brief)
 | |
| 	w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | |
| 	w.WriteHeader(200)
 | |
| 	w.Write([]byte(`{"status":"ok"}`))
 | |
| }
 | |
| 
 | |
| func (e mainEnv) getUserAgreements(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
 | |
| 	identity := ps.ByName("identity")
 | |
| 	mode := ps.ByName("mode")
 | |
| 	event := audit("privacy agreements for "+mode, identity, mode, identity)
 | |
| 	defer func() { event.submit(e.db, e.conf) }()
 | |
| 
 | |
| 	if validateMode(mode) == false {
 | |
| 		returnError(w, r, "bad mode", 405, nil, event)
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	userTOKEN := ""
 | |
| 	if mode == "token" {
 | |
| 		if enforceUUID(w, identity, event) == false {
 | |
| 			return
 | |
| 		}
 | |
| 		userBson, _ := e.db.lookupUserRecord(identity)
 | |
| 		if userBson == nil {
 | |
| 			returnError(w, r, "internal error", 405, nil, event)
 | |
| 			return
 | |
| 		}
 | |
| 		if e.enforceAuth(w, r, event) == "" {
 | |
| 			return
 | |
| 		}
 | |
| 		userTOKEN = identity
 | |
| 	} else {
 | |
| 		// TODO: decode url in code!
 | |
| 		userBson, _ := e.db.lookupUserRecordByIndex(mode, identity, e.conf)
 | |
| 		if userBson != nil {
 | |
| 			userTOKEN = userBson["token"].(string)
 | |
| 			event.Record = userTOKEN
 | |
| 			if e.enforceAuth(w, r, event) == "" {
 | |
| 				return
 | |
| 			}
 | |
| 		} else {
 | |
| 			if mode == "login" {
 | |
| 				returnError(w, r, "internal error", 405, nil, event)
 | |
| 				return
 | |
| 			}
 | |
| 			// else user not found - we allow to save consent for unlinked users!
 | |
| 
 | |
| 		}
 | |
| 	}
 | |
| 	// make sure that user is logged in here, unless he wants to cancel emails
 | |
| 	if e.enforceAuth(w, r, event) == "" {
 | |
| 		return
 | |
| 	}
 | |
| 	var resultJSON []byte
 | |
| 	var numRecords int
 | |
| 	var err error
 | |
| 	if len(userTOKEN) > 0 {
 | |
| 		resultJSON, numRecords, err = e.db.listAgreementRecords(userTOKEN)
 | |
| 	} else {
 | |
| 		resultJSON, numRecords, err = e.db.listAgreementRecordsByIdentity(identity)
 | |
| 	}
 | |
| 	if err != nil {
 | |
| 		returnError(w, r, "internal error", 405, err, event)
 | |
| 		return
 | |
| 	}
 | |
| 	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))
 | |
| }
 | |
| 
 | |
| func (e mainEnv) getUserAgreement(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
 | |
| 	identity := ps.ByName("identity")
 | |
| 	brief := ps.ByName("brief")
 | |
| 	mode := ps.ByName("mode")
 | |
| 	event := audit("privacy agreements for "+mode, identity, mode, identity)
 | |
| 	defer func() { event.submit(e.db, e.conf) }()
 | |
| 
 | |
| 	if validateMode(mode) == false {
 | |
| 		returnError(w, r, "bad mode", 405, nil, event)
 | |
| 		return
 | |
| 	}
 | |
| 	brief = normalizeBrief(brief)
 | |
| 	if isValidBrief(brief) == false {
 | |
| 		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, err, event)
 | |
| 		return
 | |
| 	}
 | |
| 	if exists == false {
 | |
| 		returnError(w, r, "not found", 404, nil, event)
 | |
| 	}
 | |
| 	userTOKEN := ""
 | |
| 	if mode == "token" {
 | |
| 		if enforceUUID(w, identity, event) == false {
 | |
| 			return
 | |
| 		}
 | |
| 		userBson, _ := e.db.lookupUserRecord(identity)
 | |
| 		if userBson == nil {
 | |
| 			returnError(w, r, "internal error", 405, nil, event)
 | |
| 			return
 | |
| 		}
 | |
| 		if e.enforceAuth(w, r, event) == "" {
 | |
| 			return
 | |
| 		}
 | |
| 		userTOKEN = identity
 | |
| 	} else {
 | |
| 		// TODO: decode url in code!
 | |
| 		userBson, _ := e.db.lookupUserRecordByIndex(mode, identity, e.conf)
 | |
| 		if userBson != nil {
 | |
| 			userTOKEN = userBson["token"].(string)
 | |
| 			event.Record = userTOKEN
 | |
| 			if e.enforceAuth(w, r, event) == "" {
 | |
| 				return
 | |
| 			}
 | |
| 		} else {
 | |
| 			if mode == "login" {
 | |
| 				returnError(w, r, "internal error", 405, nil, event)
 | |
| 				return
 | |
| 			}
 | |
| 			// else user not found - we allow to save consent for unlinked users!
 | |
| 		}
 | |
| 	}
 | |
| 	// make sure that user is logged in here, unless he wants to cancel emails
 | |
| 	if e.enforceAuth(w, r, event) == "" {
 | |
| 		return
 | |
| 	}
 | |
| 	var resultJSON []byte
 | |
| 	resultJSON, err = e.db.viewAgreementRecord(userTOKEN, brief)
 | |
| 	if err != nil {
 | |
| 		returnError(w, r, "internal error", 405, err, event)
 | |
| 		return
 | |
| 	}
 | |
| 	if resultJSON == nil {
 | |
| 		returnError(w, r, "not found", 405, err, event)
 | |
| 		return
 | |
| 	}
 | |
| 	w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | |
| 	w.WriteHeader(200)
 | |
| 	str := fmt.Sprintf(`{"status":"ok","data":%s}`, resultJSON)
 | |
| 	w.Write([]byte(str))
 | |
| }
 | |
| 
 | |
| /*
 | |
| func (e mainEnv) consentUserRecord(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
 | |
| 	identity := ps.ByName("identity")
 | |
| 	brief := ps.ByName("brief")
 | |
| 	mode := ps.ByName("mode")
 | |
| 	event := audit("consent record for "+brief, identity, mode, identity)
 | |
| 	defer func() { event.submit(e.db, e.conf) }()
 | |
| 
 | |
| 	if validateMode(mode) == false {
 | |
| 		returnError(w, r, "bad mode", 405, nil, event)
 | |
| 		return
 | |
| 	}
 | |
| 	brief = normalizeBrief(brief)
 | |
| 	if isValidBrief(brief) == false {
 | |
| 		returnError(w, r, "bad brief format", 405, nil, event)
 | |
| 		return
 | |
| 	}
 | |
| 	userTOKEN := identity
 | |
| 	var userBson bson.M
 | |
| 	if mode == "token" {
 | |
| 		if enforceUUID(w, identity, event) == false {
 | |
| 			return
 | |
| 		}
 | |
| 		userBson, _ = e.db.lookupUserRecord(identity)
 | |
| 	} else {
 | |
| 		userBson, _ = e.db.lookupUserRecordByIndex(mode, identity, e.conf)
 | |
| 		if userBson != nil {
 | |
| 			userTOKEN = userBson["token"].(string)
 | |
| 			event.Record = userTOKEN
 | |
| 		}
 | |
| 	}
 | |
| 	if userBson == nil {
 | |
| 		returnError(w, r, "internal error", 405, nil, event)
 | |
| 		return
 | |
| 	}
 | |
| 	// make sure that user is logged in here, unless he wants to cancel emails
 | |
| 	if e.enforceAuth(w, r, event) == "" {
 | |
| 		return
 | |
| 	}
 | |
| 	resultJSON, err := e.db.viewConsentRecord(userTOKEN, brief)
 | |
| 	if err != nil {
 | |
| 		returnError(w, r, "internal error", 405, err, event)
 | |
| 		return
 | |
| 	}
 | |
| 	if resultJSON == nil {
 | |
| 		returnError(w, r, "not found", 405, nil, event)
 | |
| 		return
 | |
| 	}
 | |
| 	w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | |
| 	w.WriteHeader(200)
 | |
| 	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)
 | |
| 	defer func() { event.submit(e.db, e.conf) }()
 | |
| 	if e.enforceAuth(w, r, event) == "" {
 | |
| 		return
 | |
| 	}
 | |
| 	var offset int32
 | |
| 	var limit int32 = 10
 | |
| 	args := r.URL.Query()
 | |
| 	if value, ok := args["offset"]; ok {
 | |
| 		offset = atoi(value[0])
 | |
| 	}
 | |
| 	if value, ok := args["limit"]; ok {
 | |
| 		limit = atoi(value[0])
 | |
| 	}
 | |
| 	resultJSON, numRecords, err := e.db.filterConsentRecords(brief, offset, limit)
 | |
| 	if err != nil {
 | |
| 		returnError(w, r, "internal error", 405, err, event)
 | |
| 		return
 | |
| 	}
 | |
| 	log.Printf("Total count of rows: %d\n", numRecords)
 | |
| 	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))
 | |
| }
 | |
| 
 | |
| */
 | 
