code cleanup patch from pro

This commit is contained in:
yuli
2025-02-20 10:39:46 +02:00
parent 31e91c270f
commit 922cce5e7a
23 changed files with 416 additions and 674 deletions

View File

@@ -16,16 +16,25 @@ func (e mainEnv) agreementAccept(w http.ResponseWriter, r *http.Request, ps http
identity := ps.ByName("identity")
brief := ps.ByName("brief")
mode := ps.ByName("mode")
event := audit.CreateAuditEvent("accept agreement by "+brief, identity, mode, identity)
brief = utils.NormalizeBrief(brief)
event := audit.CreateAuditEvent("accept agreement for "+brief, identity, mode, identity)
defer func() { SaveAuditEvent(event, e.db, e.conf) }()
if utils.ValidateMode(mode) == false {
utils.ReturnError(w, r, "bad mode", 405, nil, event)
strictCheck := true
if mode == "phone" || mode == "email" {
strictCheck = false
}
userTOKEN, _, err := e.getUserToken(w, r, mode, identity, event, strictCheck)
if strictCheck == true && userTOKEN == "" {
return
}
brief = utils.NormalizeBrief(brief)
if err != nil {
return
}
if utils.CheckValidBrief(brief) == false {
utils.ReturnError(w, r, "bad brief format", 405, nil, event)
utils.ReturnError(w, r, "incorrect brief format", 405, nil, event)
return
}
exists, err := e.db.checkLegalBasis(brief)
@@ -37,64 +46,32 @@ func (e mainEnv) agreementAccept(w http.ResponseWriter, r *http.Request, ps http
utils.ReturnError(w, r, "not found", 404, nil, event)
return
}
userTOKEN := ""
if mode == "token" {
if utils.EnforceUUID(w, identity, event) == false {
return
}
userBson, err := e.db.lookupUserRecord(identity)
if err != nil || userBson == nil {
utils.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 {
utils.ReturnError(w, r, "internal error", 405, err, event)
return
}
if userBson != nil {
userTOKEN = userBson["token"].(string)
event.Record = userTOKEN
} else {
if mode == "login" {
utils.ReturnError(w, r, "internal error", 405, nil, event)
return
}
// else user not found - we allow to save consent for unlinked users!
}
}
records, err := utils.GetJSONPostMap(r)
postData, err := utils.GetJSONPostMap(r)
if err != nil {
utils.ReturnError(w, r, "failed to decode request body", 405, err, event)
return
}
starttime := int32(0)
expiration := int32(0)
referencecode := utils.GetStringValue(records["referencecode"])
lastmodifiedby := utils.GetStringValue(records["lastmodifiedby"])
agreementmethod := utils.GetStringValue(records["agreementmethod"])
status := utils.GetStringValue(records["status"])
referencecode := utils.GetStringValue(postData["referencecode"])
lastmodifiedby := utils.GetStringValue(postData["lastmodifiedby"])
agreementmethod := utils.GetStringValue(postData["agreementmethod"])
status := utils.GetStringValue(postData["status"])
if len(status) == 0 {
status = "yes"
} else {
status = utils.NormalizeConsentValue(status)
}
if value, ok := records["expiration"]; ok {
switch records["expiration"].(type) {
if value, ok := postData["expiration"]; ok {
switch postData["expiration"].(type) {
case string:
expiration, _ = utils.ParseExpiration(value.(string))
case float64:
expiration = int32(value.(float64))
}
}
if value, ok := records["starttime"]; ok {
switch records["starttime"].(type) {
if value, ok := postData["starttime"]; ok {
switch postData["starttime"].(type) {
case string:
starttime, _ = utils.ParseExpiration(value.(string))
case float64:
@@ -107,6 +84,7 @@ func (e mainEnv) agreementAccept(w http.ResponseWriter, r *http.Request, ps http
case "phone":
identity = utils.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)
@@ -130,15 +108,23 @@ func (e mainEnv) agreementWithdraw(w http.ResponseWriter, r *http.Request, ps ht
identity := ps.ByName("identity")
brief := ps.ByName("brief")
mode := ps.ByName("mode")
event := audit.CreateAuditEvent("withdraw agreement by "+brief, identity, mode, identity)
defer func() { SaveAuditEvent(event, e.db, e.conf) }()
if utils.ValidateMode(mode) == false {
utils.ReturnError(w, r, "bad mode", 405, nil, event)
return
}
brief = utils.NormalizeBrief(brief)
event := audit.CreateAuditEvent("withdraw agreement for "+brief, identity, mode, identity)
defer func() { SaveAuditEvent(event, e.db, e.conf) }()
strictCheck := true
if mode == "phone" || mode == "email" {
strictCheck = false
}
userTOKEN, userBSON, err := e.getUserToken(w, r, mode, identity, event, strictCheck)
if strictCheck == true && userTOKEN == "" {
//log.Printf("Strict check err")
return
}
if err != nil {
return
}
if utils.CheckValidBrief(brief) == false {
utils.ReturnError(w, r, "bad brief format", 405, nil, event)
return
@@ -152,42 +138,12 @@ func (e mainEnv) agreementWithdraw(w http.ResponseWriter, r *http.Request, ps ht
utils.ReturnError(w, r, "not found", 405, nil, event)
return
}
userTOKEN := ""
authResult := ""
if mode == "token" {
if utils.EnforceUUID(w, identity, event) == false {
return
}
userBson, _ := e.db.lookupUserRecord(identity)
if userBson == nil {
utils.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" {
utils.ReturnError(w, r, "internal error", 405, nil, event)
return
}
// else user not found - we allow to save consent for unlinked users!
}
}
records, err := utils.GetJSONPostMap(r)
postData, err := utils.GetJSONPostMap(r)
if err != nil {
utils.ReturnError(w, r, "failed to decode request body", 405, err, event)
return
}
lastmodifiedby := utils.GetStringValue(records["lastmodifiedby"])
lastmodifiedby := utils.GetStringValue(postData["lastmodifiedby"])
selfService := false
if value, ok := lbasis["usercontrol"]; ok {
if reflect.TypeOf(value).Kind() == reflect.Bool {
@@ -199,6 +155,7 @@ func (e mainEnv) agreementWithdraw(w http.ResponseWriter, r *http.Request, ps ht
}
}
}
authResult := e.EnforceAuth(w, r, event)
if selfService == false {
// user can change consent only for briefs defined in self-service
if len(authResult) == 0 {
@@ -207,9 +164,8 @@ func (e mainEnv) agreementWithdraw(w http.ResponseWriter, r *http.Request, ps ht
}
}
}
if authResult == "login" && selfService == false {
rtoken, rstatus, err := e.db.saveUserRequest("agreement-withdraw", userTOKEN, "", brief, nil, e.conf)
rtoken, rstatus, err := e.db.saveUserRequest("agreement-withdraw", userTOKEN, userBSON, "", brief, nil, e.conf)
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, event)
return
@@ -239,10 +195,10 @@ func (e mainEnv) agreementWithdraw(w http.ResponseWriter, r *http.Request, ps ht
func (e mainEnv) agreementRevokeAll(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
brief := ps.ByName("brief")
brief = utils.NormalizeBrief(brief)
if e.EnforceAdmin(w, r, nil) == "" {
return
}
brief = utils.NormalizeBrief(brief)
if utils.CheckValidBrief(brief) == false {
utils.ReturnError(w, r, "bad brief format", 405, nil, nil)
return
@@ -265,48 +221,11 @@ func (e mainEnv) agreementRevokeAll(w http.ResponseWriter, r *http.Request, ps h
func (e mainEnv) getUserAgreements(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
identity := ps.ByName("identity")
mode := ps.ByName("mode")
event := audit.CreateAuditEvent("privacy agreements for "+mode, identity, mode, identity)
event := audit.CreateAuditEvent("get agreements for "+mode, identity, mode, identity)
defer func() { SaveAuditEvent(event, e.db, e.conf) }()
if utils.ValidateMode(mode) == false {
utils.ReturnError(w, r, "bad mode", 405, nil, event)
return
}
userTOKEN := ""
if mode == "token" {
if utils.EnforceUUID(w, identity, event) == false {
return
}
userBson, _ := e.db.lookupUserRecord(identity)
if userBson == nil {
utils.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" {
utils.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) == "" {
userTOKEN, _, _ := e.getUserToken(w, r, mode, identity, event, true)
if userTOKEN == "" {
return
}
var resultJSON []byte
@@ -317,6 +236,7 @@ func (e mainEnv) getUserAgreements(w http.ResponseWriter, r *http.Request, ps ht
} else {
resultJSON, numRecords, err = e.db.listAgreementRecordsByIdentity(identity)
}
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, event)
return
@@ -331,14 +251,15 @@ func (e mainEnv) getUserAgreement(w http.ResponseWriter, r *http.Request, ps htt
identity := ps.ByName("identity")
brief := ps.ByName("brief")
mode := ps.ByName("mode")
event := audit.CreateAuditEvent("privacy agreements for "+mode, identity, mode, identity)
brief = utils.NormalizeBrief(brief)
event := audit.CreateAuditEvent("get agreements for "+brief, identity, mode, identity)
defer func() { SaveAuditEvent(event, e.db, e.conf) }()
if utils.ValidateMode(mode) == false {
utils.ReturnError(w, r, "bad mode", 405, nil, event)
userTOKEN, _, _ := e.getUserToken(w, r, mode, identity, event, true)
if userTOKEN == "" {
return
}
brief = utils.NormalizeBrief(brief)
if utils.CheckValidBrief(brief) == false {
utils.ReturnError(w, r, "bad brief format", 405, nil, event)
return
@@ -352,43 +273,8 @@ func (e mainEnv) getUserAgreement(w http.ResponseWriter, r *http.Request, ps htt
utils.ReturnError(w, r, "not found", 404, nil, event)
return
}
userTOKEN := ""
if mode == "token" {
if utils.EnforceUUID(w, identity, event) == false {
return
}
userBson, _ := e.db.lookupUserRecord(identity)
if userBson == nil {
utils.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" {
utils.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)
resultJSON, err := e.db.viewAgreementRecord(userTOKEN, brief)
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, event)
return
@@ -430,7 +316,7 @@ func (e mainEnv) consentUserRecord(w http.ResponseWriter, r *http.Request, ps ht
} else {
userBson, _ = e.db.lookupUserRecordByIndex(mode, identity, e.conf)
if userBson != nil {
userTOKEN = userBson["token"].(string)
userTOKEN = utils.GetUuidString(userBson["token"])
event.Record = userTOKEN
}
}

View File

@@ -95,7 +95,10 @@ func (dbobj dbcon) acceptAgreement(userTOKEN string, mode string, identity strin
func (dbobj dbcon) linkAgreementRecords(userTOKEN string, encIdentity string) error {
bdoc := bson.M{}
bdoc["token"] = userTOKEN
_, err := dbobj.store.UpdateRecord2(storage.TblName.Agreements, "token", "", "who", encIdentity, &bdoc, nil)
_, err := dbobj.store.UpdateRecord(storage.TblName.Agreements, "who", encIdentity, &bdoc)
if err != nil {
log.Printf("db error: %s", err)
}
return err
}
@@ -114,7 +117,6 @@ func (dbobj dbcon) withdrawAgreement(userTOKEN string, brief string, mode string
bdoc["status"] = "no"
bdoc["lastmodifiedby"] = lastmodifiedby
if len(userTOKEN) > 0 {
log.Printf("%s %s\n", userTOKEN, brief)
dbobj.store.UpdateRecord2(storage.TblName.Agreements, "token", userTOKEN, "brief", brief, &bdoc, nil)
} else if len(identity) > 0 {
dbobj.store.UpdateRecord2(storage.TblName.Agreements, "who", encIdentity, "brief", brief, &bdoc, nil)
@@ -132,6 +134,7 @@ func (dbobj dbcon) listAgreementRecords(userTOKEN string) ([]byte, int, error) {
return []byte("[]"), 0, err
}
for _, rec := range records {
rec["token"] = utils.GetUuidString(rec["token"])
encIdentity := rec["who"].(string)
if len(encIdentity) > 0 {
identity, _ := utils.BasicStringDecrypt(encIdentity, dbobj.masterKey, dbobj.GetCode())
@@ -159,6 +162,7 @@ func (dbobj dbcon) listAgreementRecordsByIdentity(identity string) ([]byte, int,
return []byte("[]"), 0, err
}
for _, rec := range records {
rec["token"] = utils.GetUuidString(rec["token"])
rec["who"] = identity
}
resultJSON, err := json.Marshal(records)
@@ -174,6 +178,7 @@ func (dbobj dbcon) viewAgreementRecord(userTOKEN string, brief string) ([]byte,
if record == nil || err != nil {
return nil, err
}
record["token"] = utils.GetUuidString(record["token"])
encIdentity := record["who"].(string)
if len(encIdentity) > 0 {
identity, _ := utils.BasicStringDecrypt(encIdentity, dbobj.masterKey, dbobj.GetCode())
@@ -200,7 +205,7 @@ func (dbobj dbcon) expireAgreementRecords(notifyURL string) error {
bdoc := bson.M{}
bdoc["when"] = now
bdoc["status"] = "expired"
userTOKEN := rec["token"].(string)
userTOKEN := utils.GetUuidString(rec["token"])
brief := rec["brief"].(string)
log.Printf("This agreement record is expired: %s - %s\n", userTOKEN, brief)
if len(userTOKEN) > 0 {

View File

@@ -176,8 +176,12 @@ func (dbobj dbcon) getAuditEvent(atoken string) (string, []byte, error) {
return userTOKEN, nil, errors.New("empty token")
}
userTOKEN, _ = utils.BasicStringDecrypt(userTOKENEnc, dbobj.masterKey, dbobj.GetCode())
userBSON, err := dbobj.lookupUserRecord(userTOKEN)
if err != nil {
return "", nil, err
}
if len(before) > 0 {
before2, after2, _ := dbobj.userDecrypt2(userTOKEN, before, after)
before2, after2, _ := dbobj.userDecrypt2(userBSON, before, after)
//log.Printf("before: %s", before2)
//log.Printf("after: %s", after2)
record["before"] = before2
@@ -190,7 +194,7 @@ func (dbobj dbcon) getAuditEvent(atoken string) (string, []byte, error) {
return userTOKEN, []byte(result), nil
}
if len(after) > 0 {
after2, _ := dbobj.userDecrypt(userTOKEN, after)
after2, _ := dbobj.userDecrypt(userBSON, after)
//log.Printf("after: %s", after2)
record["after"] = after2
result := fmt.Sprintf(`{"after":%s,"debug":"%s"}`, after2, debug)

View File

@@ -5,6 +5,7 @@ package main
import (
"bytes"
"compress/gzip"
"errors"
"io"
"log"
"math/rand"
@@ -22,7 +23,6 @@ import (
"github.com/securitybunker/databunker/src/autocontext"
"github.com/securitybunker/databunker/src/storage"
"github.com/securitybunker/databunker/src/utils"
"go.mongodb.org/mongo-driver/bson"
"gopkg.in/yaml.v2"
)
@@ -146,7 +146,7 @@ func (e mainEnv) metrics(w http.ResponseWriter, r *http.Request, ps httprouter.P
// backupDB API call.
func (e mainEnv) backupDB(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
if e.EnforceAuth(w, r, nil) == "" {
if e.EnforceAdmin(w, r, nil) == "" {
return
}
w.WriteHeader(200)
@@ -338,7 +338,7 @@ func (e mainEnv) setupRouter() *httprouter.Router {
router.NotFound = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(http.StatusNotFound)
w.Write([]byte(`{"status":"error", "message":"url not found"}`))
w.Write([]byte(`{"status":"error", "message":"endpoint is missing"}`))
})
router.GlobalOPTIONS = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
//if r.Header.Get("Access-Control-Request-Method") != "" {
@@ -384,27 +384,44 @@ func (e mainEnv) dbCleanup() {
}
// helper function to load user details by idex name
func (e mainEnv) loadUserToken(w http.ResponseWriter, r *http.Request, mode string, identity string, event *audit.AuditEvent) string {
func (e mainEnv) getUserToken(w http.ResponseWriter, r *http.Request, mode string, identity string, event *audit.AuditEvent, strictCheck bool) (string, map[string]interface{}, error) {
var userBSON map[string]interface{}
var err error
if utils.ValidateMode(mode) == false {
utils.ReturnError(w, r, "bad mode", 405, nil, event)
return ""
return "", userBSON, errors.New("bad mode")
}
var userBson bson.M
if mode == "token" {
if utils.EnforceUUID(w, identity, event) == false {
return ""
return "", userBSON, errors.New("uuid is incorrect")
}
userBson, err = e.db.lookupUserRecord(identity)
userBSON, err = e.db.lookupUserRecord(identity)
} else {
userBson, err = e.db.lookupUserRecordByIndex(mode, identity, e.conf)
userBSON, err = e.db.lookupUserRecordByIndex(mode, identity, e.conf)
}
if userBson == nil || err != nil {
if err != nil {
utils.ReturnError(w, r, "internal error", 405, nil, event)
return ""
return "", userBSON, err
}
event.Record = userBson["token"].(string)
return event.Record
userToken := utils.GetUuidString(userBSON["token"])
if len(userToken) > 0 {
if event != nil {
event.Record = userToken
}
//log.Printf("getUserToken -> EnforceAuth()")
if e.EnforceAuth(w, r, event) == "" {
//log.Printf("XToken validation error")
return "", userBSON, errors.New("incorrect access token")
}
return userToken, userBSON, nil
}
// not found
if strictCheck == true {
utils.ReturnError(w, r, "not found", 405, nil, event)
return "", userBSON, errors.New("not found")
}
// make sure to check if user is admin
return "", userBSON, nil
}
// CustomResponseWriter struct is a custom wrapper for ResponseWriter
@@ -484,7 +501,7 @@ func (e mainEnv) reqMiddleware(handler http.Handler) http.Handler {
} else {
statusCounter = 0
statusErrorCounter = 0
log.Printf("%d %s %s\n", w2.Code, r.Method, r.URL)
log.Printf("[%d] %s %s\n", w2.Code, r.Method, r.URL)
}
})
}

View File

@@ -23,7 +23,7 @@ func helpServe0(request *http.Request) ([]byte, error) {
request.Header.Set("Content-Type", "application/json")
rr := httptest.NewRecorder()
router.ServeHTTP(rr, request)
log.Printf("[%d] %s%s\n", rr.Code, request.Host, request.URL.Path)
log.Printf("[%d] %s %s\n", rr.Code, request.Method, request.URL.Path)
if rr.Code != 200 {
return rr.Body.Bytes(), fmt.Errorf("wrong status: %d", rr.Code)
}
@@ -35,7 +35,7 @@ func helpServe(request *http.Request) (map[string]interface{}, error) {
request.Header.Set("Content-Type", "application/json")
rr := httptest.NewRecorder()
router.ServeHTTP(rr, request)
log.Printf("[%d] %s%s %s\n", rr.Code, request.Host, request.URL.Path, rr.Body.Bytes())
log.Printf("[%d] %s %s %s\n", rr.Code, request.Method, request.URL.Path, rr.Body.Bytes())
var raw map[string]interface{}
if rr.Body.Bytes()[0] == '{' {
json.Unmarshal(rr.Body.Bytes(), &raw)
@@ -50,7 +50,7 @@ func helpServe2(request *http.Request) (map[string]interface{}, error) {
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
rr := httptest.NewRecorder()
router.ServeHTTP(rr, request)
log.Printf("[%d] %s%s %s\n", rr.Code, request.Host, request.URL.Path, rr.Body.Bytes())
log.Printf("[%d] %s %s %s\n", rr.Code, request.Method, request.URL.Path, rr.Body.Bytes())
var raw map[string]interface{}
if rr.Body.Bytes()[0] == '{' {
json.Unmarshal(rr.Body.Bytes(), &raw)
@@ -112,8 +112,8 @@ func TestAnonPage(t *testing.T) {
{"url": "/site/site.js", "pattern": "dateFormat"},
{"url": "/site/style.css", "pattern": "html"},
{"url": "/site/user-profile.html", "pattern": "profile"},
{"url": "/not-fund-page.html", "pattern": "not found"},
{"url": "/site/not-fund-page.html", "pattern": "not found"},
{"url": "/not-found-page.html", "pattern": "endpoint is missing"},
{"url": "/site/not-found-page.html", "pattern": "url not found"},
}
for _, value := range goodJsons {
url := "http://localhost:3000" + value["url"].(string)
@@ -121,7 +121,7 @@ func TestAnonPage(t *testing.T) {
request := httptest.NewRequest("GET", url, nil)
raw, _ := helpServe0(request)
if strings.Contains(string(raw), pattern) == false {
t.Fatalf("pattern detection failed\n")
t.Fatalf("pattern detection failed for %s: %s\nresp: %s", url, pattern, string(raw))
}
}
}

View File

@@ -64,6 +64,7 @@ func TestConsentCreateWithdraw(t *testing.T) {
if _, ok := raw["status"]; !ok || raw["status"].(string) != "ok" {
t.Fatalf("Failed to get all brief codes")
}
/*
raw, _ = helpGetAllUserAgreements("email", "moshe@moshe-int.com")
if _, ok := raw["status"]; !ok || raw["status"].(string) != "ok" {
t.Fatalf("Failed to get user consents")
@@ -71,6 +72,7 @@ func TestConsentCreateWithdraw(t *testing.T) {
if raw["total"].(float64) != 0 {
t.Fatalf("Wrong number of user consents")
}
*/
raw, _ = helpCreateLBasis("test0", `{"basistype":"consent","usercontrol":true}`)
if _, ok := raw["status"]; !ok || raw["status"].(string) != "ok" {
t.Fatalf("Failed to create consent")
@@ -85,6 +87,7 @@ func TestConsentCreateWithdraw(t *testing.T) {
if _, ok := raw["status"]; !ok || raw["status"].(string) != "ok" {
t.Fatalf("Failed to accept on consent")
}
/*
raw, _ = helpGetAllUserAgreements("email", "moshe@moshe-int.com")
if _, ok := raw["status"]; !ok || raw["status"].(string) != "ok" {
t.Fatalf("Failed to get user consents")
@@ -92,6 +95,7 @@ func TestConsentCreateWithdraw(t *testing.T) {
if raw["total"].(float64) != 1 {
t.Fatalf("Wrong number of user consents")
}
*/
userJSON := `{"login":"moshe","email":"moshe@moshe-int.com","phone":"12345678"}`
raw, err := helpCreateUser(userJSON)
if err != nil {

View File

@@ -9,13 +9,12 @@ import (
"github.com/securitybunker/databunker/src/audit"
"github.com/securitybunker/databunker/src/storage"
"github.com/securitybunker/databunker/src/utils"
"go.mongodb.org/mongo-driver/bson"
)
func (e mainEnv) expUsers() error {
records, err := e.db.store.GetExpiring(storage.TblName.Users, "expstatus", "wait")
for _, rec := range records {
userTOKEN := rec["token"].(string)
userTOKEN := utils.GetUuidString(rec["token"])
resultJSON, userBSON, _ := e.db.getUser(userTOKEN)
if resultJSON != nil {
email := utils.GetStringValue(userBSON["email"])
@@ -32,31 +31,18 @@ func (e mainEnv) expUsers() error {
func (e mainEnv) expGetStatus(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
identity := ps.ByName("identity")
mode := ps.ByName("mode")
event := audit.CreateAuditEvent("get expiration status by "+mode, identity, mode, identity)
defer func() { SaveAuditEvent(event, e.db, e.conf) }()
var err error
if utils.ValidateMode(mode) == false {
utils.ReturnError(w, r, "bad mode", 405, nil, event)
userTOKEN, userBSON, _ := e.getUserToken(w, r, mode, identity, event, true)
if userTOKEN == "" {
return
}
var userBson bson.M
if mode == "token" {
if utils.EnforceUUID(w, identity, event) == false {
return
}
userBson, err = e.db.lookupUserRecord(identity)
} else {
userBson, err = e.db.lookupUserRecordByIndex(mode, identity, e.conf)
}
if userBson == nil || err != nil {
utils.ReturnError(w, r, "internal error", 405, nil, event)
return
}
userTOKEN := userBson["token"].(string)
event.Record = userTOKEN
expirationDate := utils.GetIntValue(userBson["endtime"])
expirationStatus := utils.GetStringValue(userBson["expstatus"])
expirationToken := utils.GetStringValue(userBson["exptoken"])
expirationDate := utils.GetIntValue(userBSON["endtime"])
expirationStatus := utils.GetStringValue(userBSON["expstatus"])
expirationToken := utils.GetStringValue(userBSON["exptoken"])
finalJSON := fmt.Sprintf(`{"status":"ok","exptime":%d,"expstatus":"%s","exptoken":"%s"}`,
expirationDate, expirationStatus, expirationToken)
w.Header().Set("Content-Type", "application/json; charset=utf-8")
@@ -70,28 +56,12 @@ func (e mainEnv) expCancel(w http.ResponseWriter, r *http.Request, ps httprouter
mode := ps.ByName("mode")
event := audit.CreateAuditEvent("clear user expiration by "+mode, identity, mode, identity)
defer func() { SaveAuditEvent(event, e.db, e.conf) }()
if utils.ValidateMode(mode) == false {
utils.ReturnError(w, r, "bad mode", 405, nil, event)
return
}
userTOKEN := identity
var userBson bson.M
if mode == "token" {
if utils.EnforceUUID(w, identity, event) == false {
return
}
userBson, err = e.db.lookupUserRecord(identity)
} else {
userBson, err = e.db.lookupUserRecordByIndex(mode, identity, e.conf)
if userBson != nil {
userTOKEN = userBson["token"].(string)
event.Record = userTOKEN
}
}
if userBson == nil || err != nil {
utils.ReturnError(w, r, "internal error", 405, nil, event)
userTOKEN, _, _ := e.getUserToken(w, r, mode, identity, event, true)
if userTOKEN == "" {
return
}
status := ""
err = e.db.updateUserExpStatus(userTOKEN, status)
if err != nil {
@@ -117,7 +87,7 @@ func (e mainEnv) expRetainData(w http.ResponseWriter, r *http.Request, ps httpro
utils.ReturnError(w, r, "internal error", 405, nil, event)
return
}
userTOKEN := userBson["token"].(string)
userTOKEN := utils.GetUuidString(userBson["token"])
event.Record = userTOKEN
status := "retain"
err = e.db.updateUserExpStatus(userTOKEN, status)
@@ -164,22 +134,25 @@ func (e mainEnv) expStart(w http.ResponseWriter, r *http.Request, ps httprouter.
event := audit.CreateAuditEvent("initiate user record expiration by "+mode, identity, mode, identity)
defer func() { SaveAuditEvent(event, e.db, e.conf) }()
if e.EnforceAdmin(w, r, event) == "" {
return
}
userTOKEN := e.loadUserToken(w, r, mode, identity, event)
userTOKEN, _, _ := e.getUserToken(w, r, mode, identity, event, true)
if userTOKEN == "" {
return
}
records, err := utils.GetJSONPostMap(r)
//only admin should do this request?
authResult := e.EnforceAdmin(w, r, event)
if authResult == "" {
return
}
postData, err := utils.GetJSONPostMap(r)
if err != nil {
utils.ReturnError(w, r, "failed to decode request body", 405, err, event)
return
}
expirationStr := utils.GetStringValue(records["expiration"])
expirationStr := utils.GetStringValue(postData["expiration"])
expiration := utils.SetExpiration(e.conf.Policy.MaxUserRetentionPeriod, expirationStr)
endtime, _ := utils.ParseExpiration(expiration)
status := utils.GetStringValue(records["status"])
status := utils.GetStringValue(postData["status"])
if len(status) == 0 {
status = "wait"
}

View File

@@ -20,30 +20,30 @@ func (e mainEnv) createLegalBasis(w http.ResponseWriter, r *http.Request, ps htt
utils.ReturnError(w, r, "bad brief format", 405, nil, nil)
return
}
records, err := utils.GetJSONPostMap(r)
postData, err := utils.GetJSONPostMap(r)
if err != nil {
utils.ReturnError(w, r, "failed to decode request body", 405, err, nil)
return
}
newbrief := utils.GetStringValue(records["brief"])
newbrief := utils.GetStringValue(postData["brief"])
if len(newbrief) > 0 && newbrief != brief {
if utils.CheckValidBrief(newbrief) == false {
utils.ReturnError(w, r, "bad brief format", 405, nil, nil)
return
}
}
status := utils.GetStringValue(records["status"])
module := utils.GetStringValue(records["module"])
fulldesc := utils.GetStringValue(records["fulldesc"])
shortdesc := utils.GetStringValue(records["shortdesc"])
basistype := utils.GetStringValue(records["basistype"])
requiredmsg := utils.GetStringValue(records["requiredmsg"])
status := utils.GetStringValue(postData["status"])
module := utils.GetStringValue(postData["module"])
fulldesc := utils.GetStringValue(postData["fulldesc"])
shortdesc := utils.GetStringValue(postData["shortdesc"])
basistype := utils.GetStringValue(postData["basistype"])
requiredmsg := utils.GetStringValue(postData["requiredmsg"])
usercontrol := false
requiredflag := false
if status != "disabled" {
status = "active"
}
if value, ok := records["usercontrol"]; ok {
if value, ok := postData["usercontrol"]; ok {
if reflect.TypeOf(value).Kind() == reflect.Bool {
usercontrol = value.(bool)
} else {
@@ -53,7 +53,7 @@ func (e mainEnv) createLegalBasis(w http.ResponseWriter, r *http.Request, ps htt
}
}
}
if value, ok := records["requiredflag"]; ok {
if value, ok := postData["requiredflag"]; ok {
if reflect.TypeOf(value).Kind() == reflect.Bool {
requiredflag = value.(bool)
} else {

View File

@@ -172,7 +172,7 @@ func (dbobj dbcon) checkLegalBasis(brief string) (bool, error) {
return true, nil
}
func (dbobj dbcon) getLegalBasis(brief string) (bson.M, error) {
func (dbobj dbcon) getLegalBasis(brief string) (map[string]interface{}, error) {
row, err := dbobj.store.GetRecord(storage.TblName.Legalbasis, "brief", brief)
if err != nil {
log.Printf("error to find: %s\n", err)

View File

@@ -13,7 +13,8 @@ import (
// This function retrieves all requests that require admin approval. This function supports result pager.
func (e mainEnv) getUserRequests(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
if e.EnforceAuth(w, r, nil) == "" {
event := audit.CreateAuditEvent("view user requests", "", "", "")
if e.EnforceAdmin(w, r, event) == "" {
return
}
var offset int32
@@ -31,7 +32,7 @@ func (e mainEnv) getUserRequests(w http.ResponseWriter, r *http.Request, ps http
}
resultJSON, counter, err := e.db.getRequests(status, offset, limit)
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, nil)
utils.ReturnError(w, r, "internal error", 405, err, event)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
@@ -47,13 +48,11 @@ func (e mainEnv) getCustomUserRequests(w http.ResponseWriter, r *http.Request, p
event := audit.CreateAuditEvent("get user privacy requests", identity, mode, identity)
defer func() { SaveAuditEvent(event, e.db, e.conf) }()
if e.EnforceAuth(w, r, event) == "" {
return
}
userTOKEN := e.loadUserToken(w, r, mode, identity, event)
userTOKEN, _, _ := e.getUserToken(w, r, mode, identity, event, true)
if userTOKEN == "" {
return
}
var offset int32
var limit int32 = 10
args := r.URL.Query()
@@ -97,17 +96,22 @@ func (e mainEnv) getUserRequest(w http.ResponseWriter, r *http.Request, ps httpr
if len(userTOKEN) != 0 {
event.Record = userTOKEN
}
if e.EnforceAdmin(w, r, event) == "" {
if e.EnforceAuth(w, r, event) == "" {
return
}
change := utils.GetStringValue(requestInfo["change"])
appName := utils.GetStringValue(requestInfo["app"])
brief := utils.GetStringValue(requestInfo["brief"])
if strings.HasPrefix(action, "plugin") {
brief = ""
}
userBSON, err := e.db.lookupUserRecord(userTOKEN)
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, event)
return
}
if len(appName) > 0 {
resultJSON, err = e.db.getUserApp(userTOKEN, appName, e.conf)
resultJSON, err = e.db.getUserApp(userTOKEN, userBSON, appName, e.conf)
} else if len(brief) > 0 {
resultJSON, err = e.db.viewAgreementRecord(userTOKEN, brief)
} else {
@@ -134,8 +138,15 @@ func (e mainEnv) getUserRequest(w http.ResponseWriter, r *http.Request, ps httpr
if len(resultJSON) > 0 {
str = fmt.Sprintf(`%s,"original":%s`, str, resultJSON)
}
if len(change) > 0 {
str = fmt.Sprintf(`%s,"change":%s`, str, change)
if value, ok := requestInfo["change"]; ok {
change := value.(string)
//recBson := bson.M{}
if len(change) > 0 {
change2, _ := e.db.userDecrypt(userBSON, change)
//log.Printf("change: %s", change2)
requestInfo["change"] = change2
str = fmt.Sprintf(`%s,"change":%s`, str, string(change2))
}
}
str = fmt.Sprintf(`{%s}`, str)
//fmt.Printf("result: %s\n", str)
@@ -154,12 +165,12 @@ func (e mainEnv) approveUserRequest(w http.ResponseWriter, r *http.Request, ps h
if authResult == "" {
return
}
records, err := utils.GetJSONPostMap(r)
postData, err := utils.GetJSONPostMap(r)
if err != nil {
utils.ReturnError(w, r, "failed to decode request body", 405, err, event)
return
}
reason := utils.GetStringValue(records["reason"])
reason := utils.GetStringValue(postData["reason"])
requestInfo, err := e.db.getRequest(request)
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, event)
@@ -188,6 +199,16 @@ func (e mainEnv) approveUserRequest(w http.ResponseWriter, r *http.Request, ps h
utils.ReturnError(w, r, "not found", 405, err, event)
return
}
if value, ok := requestInfo["change"]; ok {
change := value.(string)
//recBson := bson.M{}
if len(change) > 0 {
change2, _ := e.db.userDecrypt(userBSON, change)
//log.Printf("change: %s", change2)
requestInfo["change"] = change2
}
}
if action == "forget-me" {
email := utils.GetStringValue(userBSON["email"])
if len(email) > 0 {
@@ -220,7 +241,7 @@ func (e mainEnv) approveUserRequest(w http.ResponseWriter, r *http.Request, ps h
notifyProfileChange(notifyURL, oldJSON, newJSON, "token", userTOKEN)
} else if action == "change-app-data" {
app := requestInfo["app"].(string)
_, err = e.db.updateAppRecord(requestInfo["change"].([]uint8), userTOKEN, app, event, e.conf)
_, err = e.db.updateAppRecord(requestInfo["change"].([]uint8), userTOKEN, userBSON, app, event, e.conf)
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, event)
return
@@ -234,6 +255,7 @@ func (e mainEnv) approveUserRequest(w http.ResponseWriter, r *http.Request, ps h
pluginid := requestInfo["brief"].(string)
e.pluginUserDelete(pluginid, userTOKEN)
}
e.db.updateRequestStatus(request, "approved", reason)
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(200)
@@ -248,12 +270,12 @@ func (e mainEnv) cancelUserRequest(w http.ResponseWriter, r *http.Request, ps ht
if utils.EnforceUUID(w, request, event) == false {
return
}
records, err := utils.GetJSONPostMap(r)
postData, err := utils.GetJSONPostMap(r)
if err != nil {
utils.ReturnError(w, r, "failed to decode request body", 405, err, event)
return
}
reason := utils.GetStringValue(records["reason"])
reason := utils.GetStringValue(postData["reason"])
requestInfo, err := e.db.getRequest(request)
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, event)

View File

@@ -7,24 +7,11 @@ import (
uuid "github.com/hashicorp/go-uuid"
"github.com/securitybunker/databunker/src/storage"
"github.com/securitybunker/databunker/src/utils"
"go.mongodb.org/mongo-driver/bson"
)
type requestEvent struct {
// time for update?
Creationtime int32 `json:"creationtime"`
When int32 `json:"when"`
Token string `json:"token"`
App string `json:"app,omitempty"`
Brief string `json:"brief,omitempty"`
Action string `json:"action"`
Status string `json:"status"`
Change string `json:"change,omitempty"`
Rtoken string `json:"rtoken"`
Reason string `json:"reason"`
}
func (dbobj dbcon) saveUserRequest(action string, token string, app string, brief string, change []byte, cfg Config) (string, string, error) {
func (dbobj dbcon) saveUserRequest(action, token string, userBSON map[string]interface{}, app, brief string, change []byte, cfg Config) (string, string, error) {
now := int32(time.Now().Unix())
bdoc := bson.M{}
bdoc["token"] = token
@@ -39,14 +26,14 @@ func (dbobj dbcon) saveUserRequest(action string, token string, app string, brie
record, err := dbobj.store.LookupRecord(storage.TblName.Requests, bdoc)
if record != nil {
fmt.Printf("This record already exists.\n")
return record["rtoken"].(string), "request-exists", nil
return utils.GetUuidString(record["rtoken"]), "request-exists", nil
}
rtoken, _ := uuid.GenerateUUID()
bdoc["when"] = now
bdoc["rtoken"] = rtoken
bdoc["creationtime"] = now
if change != nil {
encodedStr, err := dbobj.userEncrypt(token, change)
encodedStr, err := dbobj.userEncrypt(userBSON, change)
if err != nil {
return "", "", err
}
@@ -71,7 +58,6 @@ func (dbobj dbcon) getRequests(status string, offset int32, limit int32) ([]byte
if count == 0 {
return []byte("[]"), 0, err
}
var results []bson.M
records, err := dbobj.store.GetList(storage.TblName.Requests, "status", status, offset, limit, "when")
if err != nil {
return nil, 0, err
@@ -82,7 +68,8 @@ func (dbobj dbcon) getRequests(status string, offset int32, limit int32) ([]byte
element["more"] = true
delete(element, "change")
}
results = append(results, element)
element["token"] = utils.GetUuidString(element["token"])
element["rtoken"] = utils.GetUuidString(element["rtoken"])
}
resultJSON, err := json.Marshal(records)
@@ -109,6 +96,8 @@ func (dbobj dbcon) getUserRequests(userTOKEN string, offset int32, limit int32)
element["more"] = true
delete(element, "change")
}
element["token"] = userTOKEN
element["rtoken"] = utils.GetUuidString(element["rtoken"])
results = append(results, element)
}
@@ -119,7 +108,7 @@ func (dbobj dbcon) getUserRequests(userTOKEN string, offset int32, limit int32)
return resultJSON, count, nil
}
func (dbobj dbcon) getRequest(rtoken string) (bson.M, error) {
func (dbobj dbcon) getRequest(rtoken string) (map[string]interface{}, error) {
record, err := dbobj.store.GetRecord(storage.TblName.Requests, "rtoken", rtoken)
if err != nil {
return record, err
@@ -129,19 +118,10 @@ func (dbobj dbcon) getRequest(rtoken string) (bson.M, error) {
}
//fmt.Printf("request record: %s\n", record)
userTOKEN := ""
change := ""
if value, ok := record["token"]; ok {
userTOKEN = value.(string)
}
if value, ok := record["change"]; ok {
change = value.(string)
}
//recBson := bson.M{}
if len(change) > 0 {
change2, _ := dbobj.userDecrypt(userTOKEN, change)
//log.Printf("change: %s", change2)
record["change"] = change2
}
userTOKEN = utils.GetUuidString(record["token"])
record["token"] = userTOKEN
record["rtoken"] = utils.GetUuidString(record["rtoken"])
return record, nil
}

View File

@@ -12,7 +12,6 @@ import (
"github.com/securitybunker/databunker/src/audit"
"github.com/securitybunker/databunker/src/storage"
"github.com/securitybunker/databunker/src/utils"
"go.mongodb.org/mongo-driver/bson"
)
func (e mainEnv) createSession(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
@@ -30,25 +29,25 @@ func (e mainEnv) createSession(w http.ResponseWriter, r *http.Request, ps httpro
if e.EnforceAdmin(w, r, event) == "" {
return
}
records, err := utils.GetJSONPostMap(r)
postData, err := utils.GetJSONPostMap(r)
if err != nil {
utils.ReturnError(w, r, "failed to decode request body", 405, err, event)
return
}
if len(records) == 0 {
if len(postData) == 0 {
utils.ReturnError(w, r, "empty body", 405, nil, event)
return
}
expirationStr := utils.GetStringValue(records["expiration"])
expirationStr := utils.GetStringValue(postData["expiration"])
expiration := utils.SetExpiration(e.conf.Policy.MaxSessionRetentionPeriod, expirationStr)
log.Printf("Record expiration: %s", expiration)
userToken := utils.GetStringValue(records["token"])
userLogin := utils.GetStringValue(records["login"])
userEmail := utils.GetStringValue(records["email"])
userPhone := utils.GetStringValue(records["phone"])
userCustomIdx := utils.GetStringValue(records["custom"])
userToken := utils.GetStringValue(postData["token"])
userLogin := utils.GetStringValue(postData["login"])
userEmail := utils.GetStringValue(postData["email"])
userPhone := utils.GetStringValue(postData["phone"])
userCustomIdx := utils.GetStringValue(postData["custom"])
var userBson bson.M
var userBson map[string]interface{}
if len(userLogin) > 0 {
userBson, err = e.db.lookupUserRecordByIndex("login", userLogin, e.conf)
} else if len(userEmail) > 0 {
@@ -67,10 +66,10 @@ func (e mainEnv) createSession(w http.ResponseWriter, r *http.Request, ps httpro
userTOKEN := ""
if userBson != nil {
event = audit.CreateAuditEvent("create session", session, "session", session)
userTOKEN = userBson["token"].(string)
userTOKEN = utils.GetUuidString(userBson["token"])
event.Record = userTOKEN
}
jsonData, err := json.Marshal(records)
jsonData, err := json.Marshal(postData)
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, event)
return
@@ -109,26 +108,23 @@ func (e mainEnv) newUserSession(w http.ResponseWriter, r *http.Request, ps httpr
event := audit.CreateAuditEvent("create user session by "+mode, identity, mode, identity)
defer func() { SaveAuditEvent(event, e.db, e.conf) }()
userTOKEN := e.loadUserToken(w, r, mode, identity, event)
userTOKEN, _, _ := e.getUserToken(w, r, mode, identity, event, true)
if userTOKEN == "" {
return
}
if e.EnforceAuth(w, r, event) == "" {
return
}
records, err := utils.GetJSONPostMap(r)
postData, err := utils.GetJSONPostMap(r)
if err != nil {
utils.ReturnError(w, r, "failed to decode request body", 405, err, event)
return
}
if len(records) == 0 {
if len(postData) == 0 {
utils.ReturnError(w, r, "empty body", 405, nil, event)
return
}
expirationStr := utils.GetStringValue(records["expiration"])
expirationStr := utils.GetStringValue(postData["expiration"])
expiration := utils.SetExpiration(e.conf.Policy.MaxSessionRetentionPeriod, expirationStr)
log.Printf("Record expiration: %s", expiration)
jsonData, err := json.Marshal(records)
jsonData, err := json.Marshal(postData)
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, event)
return
@@ -154,13 +150,11 @@ func (e mainEnv) getUserSessions(w http.ResponseWriter, r *http.Request, ps http
event := audit.CreateAuditEvent("get all user sessions", identity, mode, identity)
defer func() { SaveAuditEvent(event, e.db, e.conf) }()
userTOKEN := e.loadUserToken(w, r, mode, identity, event)
userTOKEN, _, _ := e.getUserToken(w, r, mode, identity, event, true)
if userTOKEN == "" {
return
}
if e.EnforceAuth(w, r, event) == "" {
return
}
e.db.store.DeleteExpired(storage.TblName.Sessions, "token", userTOKEN)
args := r.URL.Query()
var offset int32

View File

@@ -70,7 +70,7 @@ func (dbobj dbcon) getSession(sessionUUID string) (int32, []byte, string, error)
return 0, nil, "", errors.New("session expired")
}
when := record["when"].(int32)
userTOKEN := record["token"].(string)
userTOKEN := utils.GetUuidString(record["token"])
encData0 := record["data"].(string)
recordKey0 := record["key"].(string)
recordKey, err := base64.StdEncoding.DecodeString(recordKey0)

View File

@@ -56,7 +56,7 @@ func TestCreateQuickSession(t *testing.T) {
}
sessionTOKEN := raw["session"].(string)
time.Sleep(5 * time.Second)
log.Printf("After delay--------")
log.Printf("After delay")
raw, _ = helpGetSession(sessionTOKEN)
log.Printf("Got: %v", raw)
if _, ok := raw["status"]; !ok || raw["status"].(string) == "ok" {
@@ -74,6 +74,7 @@ func TestCreateSessionRecord(t *testing.T) {
t.Fatalf("failed to create user")
}
userTOKEN := raw["token"].(string)
log.Printf("Created user token %s", userTOKEN)
data := `{"expiration":"1m","cookie":"abcdefg","login":"alex"}`
sid, _ := uuid.GenerateUUID()
raw, _ = helpCreateSession(sid, data)

View File

@@ -20,39 +20,28 @@ func (e mainEnv) newSharedRecord(w http.ResponseWriter, r *http.Request, ps http
event := audit.CreateAuditEvent("create shareable record by "+mode, identity, "token", identity)
defer func() { SaveAuditEvent(event, e.db, e.conf) }()
userTOKEN := e.loadUserToken(w, r, mode, identity, event)
userTOKEN, _, _ := e.getUserToken(w, r, mode, identity, event, true)
if userTOKEN == "" {
return
}
if e.EnforceAuth(w, r, event) == "" {
return
}
records, err := utils.GetJSONPostMap(r)
postData, err := utils.GetJSONPostMap(r)
if err != nil {
utils.ReturnError(w, r, "failed to decode request body", 405, err, event)
return
}
fields := ""
session := ""
partner := ""
appName := ""
fields := utils.GetStringValue(postData["fields"])
session := utils.GetStringValue(postData["session"])
partner := utils.GetStringValue(postData["partner"])
appName := utils.GetStringValue(postData["app"])
expiration := e.conf.Policy.MaxShareableRecordRetentionPeriod
if value, ok := records["fields"]; ok {
if reflect.TypeOf(value) == reflect.TypeOf("string") {
fields = value.(string)
if len(appName) > 0 {
appName = strings.ToLower(appName)
if utils.CheckValidApp(appName) == false {
utils.ReturnError(w, r, "unknown app name", 405, nil, event)
}
}
if value, ok := records["session"]; ok {
if reflect.TypeOf(value) == reflect.TypeOf("string") {
session = value.(string)
}
}
if value, ok := records["partner"]; ok {
if reflect.TypeOf(value) == reflect.TypeOf("string") {
partner = value.(string)
}
}
if value, ok := records["expiration"]; ok {
if value, ok := postData["expiration"]; ok {
if reflect.TypeOf(value) == reflect.TypeOf("string") {
expiration = utils.SetExpiration(e.conf.Policy.MaxShareableRecordRetentionPeriod, value.(string))
} else {
@@ -60,17 +49,6 @@ func (e mainEnv) newSharedRecord(w http.ResponseWriter, r *http.Request, ps http
return
}
}
if value, ok := records["app"]; ok {
if reflect.TypeOf(value) == reflect.TypeOf("string") {
appName = strings.ToLower(value.(string))
if len(appName) > 0 && utils.CheckValidApp(appName) == false {
utils.ReturnError(w, r, "unknown app name", 405, nil, event)
}
} else {
// type is different
utils.ReturnError(w, r, "failed to parse app field", 405, nil, event)
}
}
if len(expiration) == 0 {
// using default expiration time for record
expiration = "1m"
@@ -106,10 +84,17 @@ func (e mainEnv) getRecord(w http.ResponseWriter, r *http.Request, ps httprouter
if len(recordInfo.token) > 0 {
event.Record = recordInfo.token
event.App = recordInfo.appName
log.Printf("field to display: %s, user token: %s\n", recordInfo.fields, recordInfo.token)
log.Printf("fields to display: %s, user token: %s\n", recordInfo.fields, recordInfo.token)
if len(recordInfo.appName) > 0 {
resultJSON, err = e.db.getUserApp(recordInfo.token, recordInfo.appName, e.conf)
if len(recordInfo.token) > 0 {
userBSON, err := e.db.lookupUserRecord(recordInfo.token)
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, event)
return
}
resultJSON, err = e.db.getUserApp(recordInfo.token, userBSON, recordInfo.appName, e.conf)
}
} else if len(recordInfo.session) > 0 {
_, resultJSON, _, err = e.db.getSession(recordInfo.session)
} else {
@@ -123,7 +108,7 @@ func (e mainEnv) getRecord(w http.ResponseWriter, r *http.Request, ps httprouter
utils.ReturnError(w, r, "not found", 405, err, event)
return
}
log.Printf("Full json: %s\n", resultJSON)
//log.Printf("Full json: %s\n", resultJSON)
if len(recordInfo.fields) > 0 {
raw := make(map[string]interface{})
//var newJSON json

View File

@@ -31,12 +31,6 @@ func (dbobj dbcon) saveSharedRecord(userTOKEN string, fields string, expiration
if err != nil {
return "", err
}
// check if user record exists
record, err := dbobj.lookupUserRecord(userTOKEN)
if record == nil || err != nil {
// not found
return "", errors.New("not found")
}
recordUUID, err := uuid.GenerateUUID()
if err != nil {
return "", err
@@ -81,7 +75,7 @@ func (dbobj dbcon) getSharedRecord(recordUUID string) (checkRecordResult, error)
if now > record["endtime"].(int32) {
return result, errors.New("xtoken expired")
}
result.token = record["token"].(string)
result.token = utils.GetUuidString(record["token"])
if value, ok := record["fields"]; ok {
result.fields = value.(string)
}
@@ -91,6 +85,5 @@ func (dbobj dbcon) getSharedRecord(recordUUID string) (checkRecordResult, error)
if value, ok := record["app"]; ok {
result.appName = value.(string)
}
return result, nil
}

View File

@@ -18,13 +18,11 @@ func (e mainEnv) userappNew(w http.ResponseWriter, r *http.Request, ps httproute
event := audit.CreateAuditAppEvent("create user app record by "+mode, identity, appName, mode, identity)
defer func() { SaveAuditEvent(event, e.db, e.conf) }()
userTOKEN := e.loadUserToken(w, r, mode, identity, event)
userTOKEN, userBSON, _ := e.getUserToken(w, r, mode, identity, event, true)
if userTOKEN == "" {
return
}
if e.EnforceAuth(w, r, event) == "" {
return
}
if utils.CheckValidApp(appName) == false {
utils.ReturnError(w, r, "bad appname", 405, nil, event)
return
@@ -33,22 +31,21 @@ func (e mainEnv) userappNew(w http.ResponseWriter, r *http.Request, ps httproute
utils.ReturnError(w, r, "db limitation", 405, nil, event)
return
}
data, err := utils.GetJSONPostMap(r)
postData, err := utils.GetJSONPostMap(r)
if err != nil {
utils.ReturnError(w, r, "failed to decode request body", 405, err, event)
return
}
if len(data) == 0 {
if len(postData) == 0 {
utils.ReturnError(w, r, "empty body", 405, nil, event)
return
}
jsonData, err := json.Marshal(data)
jsonData, err := json.Marshal(postData)
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, event)
return
}
_, err = e.db.createAppRecord(jsonData, userTOKEN, appName, event, e.conf)
_, err = e.db.createAppRecord(jsonData, userTOKEN, userBSON, appName, event, e.conf)
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, event)
return
@@ -63,14 +60,13 @@ func (e mainEnv) userappChange(w http.ResponseWriter, r *http.Request, ps httpro
mode := ps.ByName("mode")
event := audit.CreateAuditAppEvent("change user app record by "+mode, identity, appName, mode, identity)
defer func() { SaveAuditEvent(event, e.db, e.conf) }()
userTOKEN := e.loadUserToken(w, r, mode, identity, event)
userTOKEN, userBSON, _ := e.getUserToken(w, r, mode, identity, event, true)
if userTOKEN == "" {
return
}
authResult := e.EnforceAuth(w, r, event)
if authResult == "" {
return
}
if utils.CheckValidApp(appName) == false {
utils.ReturnError(w, r, "bad appname", 405, nil, event)
return
@@ -85,17 +81,17 @@ func (e mainEnv) userappChange(w http.ResponseWriter, r *http.Request, ps httpro
return
}
// make sure userapp exists
resultJSON, err := e.db.getUserApp(userTOKEN, appName, e.conf)
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, event)
return
}
if resultJSON == nil {
utils.ReturnError(w, r, "not found", 405, nil, event)
return
}
// resultJSON, err := e.db.getUserApp(userTOKEN, userBSON, appName, e.conf)
// if err != nil {
// utils.ReturnError(w, r, "internal error", 405, err, event)
// return
// }
// if resultJSON == nil {
// utils.ReturnError(w, r, "not found", 405, nil, event)
// return
// }
if authResult != "login" {
_, err = e.db.updateAppRecord(jsonData, userTOKEN, appName, event, e.conf)
_, err = e.db.updateAppRecord(jsonData, userTOKEN, userBSON, appName, event, e.conf)
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, event)
return
@@ -106,7 +102,7 @@ func (e mainEnv) userappChange(w http.ResponseWriter, r *http.Request, ps httpro
if e.conf.SelfService.AppRecordChange != nil {
for _, name := range e.conf.SelfService.AppRecordChange {
if utils.StringPatternMatch(strings.ToLower(name), appName) {
_, err = e.db.updateAppRecord(jsonData, userTOKEN, appName, event, e.conf)
_, err = e.db.updateAppRecord(jsonData, userTOKEN, userBSON, appName, event, e.conf)
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, event)
return
@@ -116,7 +112,7 @@ func (e mainEnv) userappChange(w http.ResponseWriter, r *http.Request, ps httpro
}
}
}
rtoken, rstatus, err := e.db.saveUserRequest("change-app-data", userTOKEN, appName, "", jsonData, e.conf)
rtoken, rstatus, err := e.db.saveUserRequest("change-app-data", userTOKEN, userBSON, appName, "", jsonData, e.conf)
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, event)
return
@@ -131,13 +127,12 @@ func (e mainEnv) userappList(w http.ResponseWriter, r *http.Request, ps httprout
mode := ps.ByName("mode")
event := audit.CreateAuditEvent("get user app list by "+mode, identity, mode, identity)
defer func() { SaveAuditEvent(event, e.db, e.conf) }()
userTOKEN := e.loadUserToken(w, r, mode, identity, event)
userTOKEN, _, _ := e.getUserToken(w, r, mode, identity, event, true)
if userTOKEN == "" {
return
}
if e.EnforceAuth(w, r, event) == "" {
return
}
result, err := e.db.listUserApps(userTOKEN, e.conf)
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, event)
@@ -154,18 +149,16 @@ func (e mainEnv) userappGet(w http.ResponseWriter, r *http.Request, ps httproute
mode := ps.ByName("mode")
event := audit.CreateAuditAppEvent("get user app record by "+mode, identity, appName, mode, identity)
defer func() { SaveAuditEvent(event, e.db, e.conf) }()
userTOKEN := e.loadUserToken(w, r, mode, identity, event)
userTOKEN, userBSON, _ := e.getUserToken(w, r, mode, identity, event, true)
if userTOKEN == "" {
return
}
if e.EnforceAuth(w, r, event) == "" {
return
}
if utils.CheckValidApp(appName) == false {
utils.ReturnError(w, r, "bad appname", 405, nil, event)
return
}
resultJSON, err := e.db.getUserApp(userTOKEN, appName, e.conf)
resultJSON, err := e.db.getUserApp(userTOKEN, userBSON, appName, e.conf)
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, event)
return
@@ -186,18 +179,16 @@ func (e mainEnv) userappDelete(w http.ResponseWriter, r *http.Request, ps httpro
mode := ps.ByName("mode")
event := audit.CreateAuditAppEvent("delete user app record by "+mode, identity, appName, mode, identity)
defer func() { SaveAuditEvent(event, e.db, e.conf) }()
userTOKEN := e.loadUserToken(w, r, mode, identity, event)
userTOKEN, _, _ := e.getUserToken(w, r, mode, identity, event, true)
if userTOKEN == "" {
return
}
if e.EnforceAuth(w, r, event) == "" {
return
}
if utils.CheckValidApp(appName) == false {
utils.ReturnError(w, r, "bad appname", 405, nil, event)
return
}
e.db.deleteUserApp(userTOKEN, appName, e.conf)
finalJSON := fmt.Sprintf(`{"status":"ok","token":"%s"}`, userTOKEN)

View File

@@ -14,7 +14,7 @@ import (
"go.mongodb.org/mongo-driver/bson"
)
func (dbobj dbcon) getUserApp(userTOKEN string, appName string, conf Config) ([]byte, error) {
func (dbobj dbcon) getUserApp(userTOKEN string, userBSON map[string]interface{}, appName string, conf Config) ([]byte, error) {
appNameFull := "app_" + appName
var record bson.M
var err error
@@ -30,7 +30,7 @@ func (dbobj dbcon) getUserApp(userTOKEN string, appName string, conf Config) ([]
return nil, nil
}
encData0 := record["data"].(string)
return dbobj.userDecrypt(userTOKEN, encData0)
return dbobj.userDecrypt(userBSON, encData0)
}
func (dbobj dbcon) deleteUserApp(userTOKEN string, appName string, conf Config) {
@@ -55,10 +55,10 @@ func (dbobj dbcon) deleteUserApps(userTOKEN string, conf Config) {
}
}
func (dbobj dbcon) createAppRecord(jsonData []byte, userTOKEN string, appName string, event *audit.AuditEvent, conf Config) (string, error) {
func (dbobj dbcon) createAppRecord(jsonData []byte, userTOKEN string, userBSON map[string]interface{}, appName string, event *audit.AuditEvent, conf Config) (string, error) {
appNameFull := "app_" + appName
//log.Printf("Going to create app record: %s\n", appName)
encodedStr, err := dbobj.userEncrypt(userTOKEN, jsonData)
encodedStr, err := dbobj.userEncrypt(userBSON, jsonData)
if err != nil {
return userTOKEN, err
}
@@ -104,16 +104,11 @@ func (dbobj dbcon) createAppRecord(jsonData []byte, userTOKEN string, appName st
return userTOKEN, err
}
func (dbobj dbcon) updateAppRecord(jsonDataPatch []byte, userTOKEN string, appName string, event *audit.AuditEvent, conf Config) (string, error) {
func (dbobj dbcon) updateAppRecord(jsonDataPatch []byte, userTOKEN string, userBSON map[string]interface{}, appName string, event *audit.AuditEvent, conf Config) (string, error) {
//_, err = collection.InsertOne(context.TODO(), bson.M{"name": "The Go Language2", "genre": "Coding", "authorId": "4"})
appNameFull := "app_" + appName
userBson, err := dbobj.lookupUserRecord(userTOKEN)
if userBson == nil || err != nil {
// not found
return userTOKEN, err
}
// get user key
userKey := userBson["key"].(string)
userKey := userBSON["key"].(string)
recordKey, err := base64.StdEncoding.DecodeString(userKey)
if err != nil {
return userTOKEN, err
@@ -196,11 +191,6 @@ func (dbobj dbcon) updateAppRecord(jsonDataPatch []byte, userTOKEN string, appNa
// go over app collections and check if we have user record inside
func (dbobj dbcon) listUserApps(userTOKEN string, conf Config) ([]byte, error) {
//_, err = collection.InsertOne(context.TODO(), bson.M{"name": "The Go Language2", "genre": "Coding", "authorId": "4"})
record, err := dbobj.lookupUserRecord(userTOKEN)
if record == nil || err != nil {
// not found
return nil, err
}
var result []string
if conf.Generic.UseSeparateAppTables == true {
allCollections, err := dbobj.store.GetAllTables()

View File

@@ -10,7 +10,6 @@ import (
"github.com/securitybunker/databunker/src/audit"
"github.com/securitybunker/databunker/src/storage"
"github.com/securitybunker/databunker/src/utils"
"go.mongodb.org/mongo-driver/bson"
)
func (e mainEnv) userCreate(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
@@ -19,7 +18,7 @@ func (e mainEnv) userCreate(w http.ResponseWriter, r *http.Request, ps httproute
if e.conf.Generic.CreateUserWithoutAccessToken == false {
// anonymous user can not create user record, check token
if e.EnforceAuth(w, r, event) == "" {
if e.EnforceAdmin(w, r, event) == "" {
log.Println("Failed to create user, access denied, try to configure Create_user_without_access_token")
return
}
@@ -124,41 +123,23 @@ func (e mainEnv) userCreate(w http.ResponseWriter, r *http.Request, ps httproute
}
func (e mainEnv) userGet(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
var err error
var resultJSON []byte
identity := ps.ByName("identity")
mode := ps.ByName("mode")
event := audit.CreateAuditEvent("get user record by "+mode, identity, mode, identity)
defer func() { SaveAuditEvent(event, e.db, e.conf) }()
if utils.ValidateMode(mode) == false {
utils.ReturnError(w, r, "bad mode", 405, nil, event)
return
}
userTOKEN := ""
authResult := ""
if mode == "token" {
if utils.EnforceUUID(w, identity, event) == false {
return
}
resultJSON, err = e.db.getUserJSON(identity)
userTOKEN = identity
} else {
resultJSON, userTOKEN, err = e.db.getUserJSONByIndex(identity, mode, e.conf)
event.Record = userTOKEN
}
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, event)
return
}
authResult = e.EnforceAuth(w, r, event)
if authResult == "" {
userTOKEN, userBSON, _ := e.getUserToken(w, r, mode, identity, event, true)
if userTOKEN == "" {
return
}
resultJSON, _ := e.db.userProfileDecrypt(userBSON)
if resultJSON == nil {
utils.ReturnError(w, r, "record not found", 405, nil, event)
return
resultJSON = []byte("{}")
}
// if resultJSON == nil {
// utils.ReturnError(w, r, "record not found", 405, nil, event)
// return
// }
finalJSON := fmt.Sprintf(`{"status":"ok","token":"%s","data":%s}`, userTOKEN, resultJSON)
//fmt.Printf("record: %s\n", finalJSON)
//fmt.Fprintf(w, "<html><head><title>title</title></head>")
@@ -173,48 +154,33 @@ func (e mainEnv) userChange(w http.ResponseWriter, r *http.Request, ps httproute
event := audit.CreateAuditEvent("change user record by "+mode, identity, mode, identity)
defer func() { SaveAuditEvent(event, e.db, e.conf) }()
if utils.ValidateMode(mode) == false {
utils.ReturnError(w, r, "bad index", 405, nil, event)
return
}
jsonData, err := utils.GetJSONPostData(r)
if err != nil {
utils.ReturnError(w, r, "failed to decode request body", 405, err, event)
return
}
if jsonData == nil {
utils.ReturnError(w, r, "empty request body", 405, nil, event)
return
}
userTOKEN := ""
var userJSON []byte
var userBSON bson.M
if mode == "token" {
if utils.EnforceUUID(w, identity, event) == false {
return
}
userTOKEN = identity
userJSON, userBSON, err = e.db.getUser(identity)
} else {
userJSON, userTOKEN, userBSON, err = e.db.getUserByIndex(identity, mode, e.conf)
event.Record = userTOKEN
}
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, event)
userTOKEN, userBSON, _ := e.getUserToken(w, r, mode, identity, event, true)
if userTOKEN == "" {
return
}
userJSON, _ := e.db.userProfileDecrypt(userBSON)
if userJSON == nil {
utils.ReturnError(w, r, "user record not found", 405, nil, event)
return
}
postData, err := utils.GetJSONPostData(r)
if err != nil {
utils.ReturnError(w, r, "failed to decode request body", 405, err, event)
return
}
if postData == nil {
utils.ReturnError(w, r, "empty request body", 405, nil, event)
return
}
authResult := e.EnforceAuth(w, r, event)
if authResult == "" {
return
}
adminRecordChanged := false
if UserSchemaEnabled() {
adminRecordChanged, err = e.db.validateUserRecordChange(userJSON, jsonData, userTOKEN, authResult)
adminRecordChanged, err = e.db.validateUserRecordChange(userJSON, postData, userTOKEN, authResult)
if err != nil {
utils.ReturnError(w, r, "schema validation error: "+err.Error(), 405, err, event)
return
@@ -223,7 +189,7 @@ func (e mainEnv) userChange(w http.ResponseWriter, r *http.Request, ps httproute
if authResult == "login" {
event.Title = "user change-profile request"
if e.conf.SelfService.UserRecordChange == false || adminRecordChanged == true {
rtoken, rstatus, err := e.db.saveUserRequest("change-profile", userTOKEN, "", "", jsonData, e.conf)
rtoken, rstatus, err := e.db.saveUserRequest("change-profile", userTOKEN, userBSON, "", "", postData, e.conf)
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, event)
return
@@ -234,7 +200,7 @@ func (e mainEnv) userChange(w http.ResponseWriter, r *http.Request, ps httproute
return
}
}
oldJSON, newJSON, lookupErr, err := e.db.updateUserRecord(jsonData, userTOKEN, userBSON, event, e.conf)
oldJSON, newJSON, lookupErr, err := e.db.updateUserRecord(postData, userTOKEN, userBSON, event, e.conf)
if lookupErr {
utils.ReturnError(w, r, "record not found", 405, errors.New("record not found"), event)
return
@@ -255,37 +221,28 @@ func (e mainEnv) userDelete(w http.ResponseWriter, r *http.Request, ps httproute
event := audit.CreateAuditEvent("delete user record by "+mode, identity, mode, identity)
defer func() { SaveAuditEvent(event, e.db, e.conf) }()
if utils.ValidateMode(mode) == false {
utils.ReturnError(w, r, "bad mode", 405, nil, event)
strictCheck := true
if mode == "email" {
strictCheck = false
}
userTOKEN, userBSON, err := e.getUserToken(w, r, mode, identity, event, strictCheck)
if strictCheck == true && userTOKEN == "" {
return
}
var err error
var userBSON bson.M
var userJSON []byte
userTOKEN := identity
if mode == "token" {
if utils.EnforceUUID(w, identity, event) == false {
return
}
userJSON, userBSON, err = e.db.getUser(identity)
} else {
userJSON, userTOKEN, userBSON, err = e.db.getUserByIndex(identity, mode, e.conf)
event.Record = userTOKEN
}
if err != nil {
utils.ReturnError(w, r, "internal error", 405, nil, event)
return
}
authResult := e.EnforceAuth(w, r, event)
if authResult == "" {
return
}
if userJSON == nil {
if len(userTOKEN) == 0 {
if authResult == "root" && mode == "email" {
e.globalUserDelete(identity)
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(200)
fmt.Fprintf(w, `{"status":"ok","result":"done"}`)
return
}
utils.ReturnError(w, r, "record not found", 405, nil, event)
return
@@ -294,7 +251,7 @@ func (e mainEnv) userDelete(w http.ResponseWriter, r *http.Request, ps httproute
if authResult == "login" {
event.Title = "user forget-me request"
if e.conf.SelfService.ForgetMe == false {
rtoken, rstatus, err := e.db.saveUserRequest("forget-me", userTOKEN, "", "", nil, e.conf)
rtoken, rstatus, err := e.db.saveUserRequest("forget-me", userTOKEN, userBSON, "", "", nil, e.conf)
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, event)
return
@@ -305,9 +262,19 @@ func (e mainEnv) userDelete(w http.ResponseWriter, r *http.Request, ps httproute
return
}
}
email := utils.GetStringValue(userBSON["email"])
if len(email) > 0 {
e.globalUserDelete(email)
// decrypt user!
userJSON, err := e.db.userProfileDecrypt(userBSON)
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, event)
return
}
if userJSON == nil {
userJSON = []byte("{}")
} else {
email := utils.GetStringValue(userBSON["email"])
if len(email) > 0 {
e.globalUserDelete(email)
}
}
//fmt.Printf("deleting user %s\n", userTOKEN)
_, err = e.db.deleteUserRecord(userJSON, userTOKEN, e.conf)
@@ -347,7 +314,7 @@ func (e mainEnv) userPrelogin(w http.ResponseWriter, r *http.Request, ps httprou
return
}
if userBson != nil {
userTOKEN := userBson["token"].(string)
userTOKEN := utils.GetUuidString(userBson["token"])
event.Record = userTOKEN
if identity == "4444" || identity == "test@securitybunker.io" {
// check if it is demo account.
@@ -398,7 +365,7 @@ func (e mainEnv) userLogin(w http.ResponseWriter, r *http.Request, ps httprouter
return
}
userTOKEN := userBson["token"].(string)
userTOKEN := utils.GetUuidString(userBson["token"])
event.Record = userTOKEN
tmpCode := int32(0)
if _, ok := userBson["tempcode"]; ok {
@@ -407,7 +374,7 @@ func (e mainEnv) userLogin(w http.ResponseWriter, r *http.Request, ps httprouter
if tmp == tmpCode {
// user ented correct key
// generate temp user access code
xtoken, hashedToken, err := e.db.generateUserLoginXtoken(userTOKEN)
xtoken, hashedToken, err := e.db.genUserLoginXtoken(userTOKEN)
//fmt.Printf("generate user access token: %s\n", xtoken)
if err != nil {
utils.ReturnError(w, r, "internal error", 405, err, event)

View File

@@ -18,7 +18,6 @@ import (
)
func (dbobj dbcon) createUserRecord(parsedData utils.UserJSONStruct, event *audit.AuditEvent) (string, error) {
var userTOKEN string
//var bdoc interface{}
bdoc := bson.M{}
userTOKEN, err := uuid.GenerateUUID()
@@ -297,11 +296,14 @@ func (dbobj dbcon) updateUserRecordDo(jsonDataPatch []byte, userTOKEN string, ol
return decrypted, newJSON, false, nil
}
func (dbobj dbcon) lookupUserRecord(userTOKEN string) (bson.M, error) {
func (dbobj dbcon) lookupUserRecord(userTOKEN string) (map[string]interface{}, error) {
if len(userTOKEN) == 0 {
return nil, nil
}
return dbobj.store.GetRecord(storage.TblName.Users, "token", userTOKEN)
}
func (dbobj dbcon) lookupUserRecordByIndex(indexName string, indexValue string, conf Config) (bson.M, error) {
func (dbobj dbcon) lookupUserRecordByIndex(indexName string, indexValue string, conf Config) (map[string]interface{}, error) {
if indexName == "email" {
indexValue = utils.NormalizeEmail(indexValue)
} else if indexName == "phone" {
@@ -319,65 +321,29 @@ func (dbobj dbcon) lookupUserRecordByIndex(indexName string, indexValue string,
}
func (dbobj dbcon) getUserJSON(userTOKEN string) ([]byte, error) {
userBson, err := dbobj.lookupUserRecord(userTOKEN)
if userBson == nil || err != nil {
userBSON, err := dbobj.lookupUserRecord(userTOKEN)
if userBSON == nil || err != nil {
// not found
return nil, err
}
if _, ok := userBson["key"]; !ok {
decrypted, err := dbobj.userProfileDecrypt(userBSON)
if decrypted == nil {
return []byte("{}"), nil
}
userKey := userBson["key"].(string)
userKeyBinary, err := base64.StdEncoding.DecodeString(userKey)
if err != nil {
return nil, err
}
var decrypted []byte
if _, ok := userBson["data"]; ok {
encData0 := userBson["data"].(string)
if len(encData0) > 0 {
encData, err := base64.StdEncoding.DecodeString(encData0)
if err != nil {
return nil, err
}
decrypted, err = utils.Decrypt(dbobj.masterKey, userKeyBinary, encData)
if err != nil {
return nil, err
}
}
}
return decrypted, err
}
func (dbobj dbcon) getUser(userTOKEN string) ([]byte, bson.M, error) {
userBson, err := dbobj.lookupUserRecord(userTOKEN)
if userBson == nil || err != nil {
func (dbobj dbcon) getUser(userTOKEN string) ([]byte, map[string]interface{}, error) {
userBSON, err := dbobj.lookupUserRecord(userTOKEN)
if userBSON == nil || err != nil {
// not found
return nil, nil, err
}
if _, ok := userBson["key"]; !ok {
return []byte("{}"), userBson, nil
decrypted, err := dbobj.userProfileDecrypt(userBSON)
if decrypted == nil {
return []byte("{}"), userBSON, err
}
userKey := userBson["key"].(string)
userKeyBinary, err := base64.StdEncoding.DecodeString(userKey)
if err != nil {
return nil, nil, err
}
var decrypted []byte
if _, ok := userBson["data"]; ok {
encData0 := userBson["data"].(string)
if len(encData0) > 0 {
encData, err := base64.StdEncoding.DecodeString(encData0)
if err != nil {
return nil, nil, err
}
decrypted, err = utils.Decrypt(dbobj.masterKey, userKeyBinary, encData)
if err != nil {
return nil, nil, err
}
}
}
return decrypted, userBson, err
return decrypted, userBSON, err
}
func (dbobj dbcon) getUsers(offset int32, limit int32) ([]byte, int64, error) {
@@ -394,37 +360,20 @@ func (dbobj dbcon) getUsers(offset int32, limit int32) ([]byte, int64, error) {
return nil, 0, err
}
for _, element := range records {
rec := make(map[string]interface{})
userKey := element["key"].(string)
userKeyBinary, err := base64.StdEncoding.DecodeString(userKey)
if err != nil {
return nil, 0, err
}
userTOKEN := element["token"].(string)
encData0 := element["data"].(string)
if len(encData0) > 0 {
encData, err := base64.StdEncoding.DecodeString(encData0)
if err != nil {
return nil, 0, err
decrypted, err := dbobj.userProfileDecrypt(element)
if err == nil {
rec := make(map[string]interface{})
userTOKEN := element["token"].(string)
rec["private"] = decrypted
expstatus := utils.GetStringValue(element["expstatus"])
if len(expstatus) > 0 {
rec["endtime"] = element["endtime"]
rec["expstatus"] = expstatus
}
decrypted, err := utils.Decrypt(dbobj.masterKey, userKeyBinary, encData)
if err != nil {
return nil, 0, err
}
var raw2 map[string]interface{}
err = json.Unmarshal(decrypted, &raw2)
if err != nil {
return nil, 0, err
}
rec["private"] = raw2
rec["token"] = userTOKEN
results = append(results, rec)
}
expstatus := utils.GetStringValue(element["expstatus"])
if len(expstatus) > 0 {
rec["endtime"] = element["endtime"]
rec["expstatus"] = expstatus
}
rec["token"] = userTOKEN
results = append(results, rec)
}
resultJSON, err := json.Marshal(results)
if err != nil {
@@ -457,62 +406,28 @@ func (dbobj dbcon) dumpUserPII(email string, conf Config) (string, error) {
}
func (dbobj dbcon) getUserJSONByIndex(indexValue string, indexName string, conf Config) ([]byte, string, error) {
userBson, err := dbobj.lookupUserRecordByIndex(indexName, indexValue, conf)
if userBson == nil || err != nil {
userBSON, err := dbobj.lookupUserRecordByIndex(indexName, indexValue, conf)
if userBSON == nil || err != nil {
return nil, "", err
}
userKey := userBson["key"].(string)
userKeyBinary, err := base64.StdEncoding.DecodeString(userKey)
if err != nil {
return nil, "", err
}
var decrypted []byte
if _, ok := userBson["data"]; ok {
encData0 := userBson["data"].(string)
if len(encData0) > 0 {
encData, err := base64.StdEncoding.DecodeString(encData0)
if err != nil {
return nil, "", err
}
decrypted, err = utils.Decrypt(dbobj.masterKey, userKeyBinary, encData)
if err != nil {
return nil, "", err
}
}
}
return decrypted, userBson["token"].(string), err
userTOKEN := utils.GetUuidString(userBSON["token"])
decrypted, err := dbobj.userProfileDecrypt(userBSON)
return decrypted, userTOKEN, err
}
func (dbobj dbcon) getUserByIndex(indexValue string, indexName string, conf Config) ([]byte, string, bson.M, error) {
userBson, err := dbobj.lookupUserRecordByIndex(indexName, indexValue, conf)
if userBson == nil || err != nil {
func (dbobj dbcon) getUserByIndex(indexValue string, indexName string, conf Config) ([]byte, string, map[string]interface{}, error) {
userBSON, err := dbobj.lookupUserRecordByIndex(indexName, indexValue, conf)
if userBSON == nil || err != nil {
return nil, "", nil, err
}
userKey := userBson["key"].(string)
userKeyBinary, err := base64.StdEncoding.DecodeString(userKey)
if err != nil {
return nil, "", nil, err
}
var decrypted []byte
if _, ok := userBson["data"]; ok {
encData0 := userBson["data"].(string)
if len(encData0) > 0 {
encData, err := base64.StdEncoding.DecodeString(encData0)
if err != nil {
return nil, "", nil, err
}
decrypted, err = utils.Decrypt(dbobj.masterKey, userKeyBinary, encData)
if err != nil {
return nil, "", nil, err
}
}
}
return decrypted, userBson["token"].(string), userBson, err
userTOKEN := utils.GetUuidString(userBSON["token"])
decrypted, err := dbobj.userProfileDecrypt(userBSON)
return decrypted, userTOKEN, userBSON, err
}
func (dbobj dbcon) deleteUserRecord(userJSON []byte, userTOKEN string, conf Config) (bool, error) {
dbobj.deleteUserApps(userTOKEN, conf)
//delete in audit
// TODO: delete in audit?
dbobj.store.DeleteRecord(storage.TblName.Audit, "record", userTOKEN)
dbobj.store.DeleteRecord(storage.TblName.Sessions, "token", userTOKEN)
@@ -600,16 +515,12 @@ func (dbobj dbcon) wipeRecord(userTOKEN string) (bool, error) {
}
*/
func (dbobj dbcon) userEncrypt(userTOKEN string, data []byte) (string, error) {
userBson, err := dbobj.lookupUserRecord(userTOKEN)
if userBson == nil || err != nil {
return "", errors.New("not found")
}
if _, ok := userBson["key"]; !ok {
func (dbobj dbcon) userEncrypt(userBSON map[string]interface{}, data []byte) (string, error) {
userKey, ok := userBSON["key"].(string)
if !ok {
// user might be deleted already
return "", errors.New("not found")
}
userKey := userBson["key"].(string)
userKeyBinary, err := base64.StdEncoding.DecodeString(userKey)
if err != nil {
return "", err
@@ -622,16 +533,41 @@ func (dbobj dbcon) userEncrypt(userTOKEN string, data []byte) (string, error) {
return encodedStr, nil
}
func (dbobj dbcon) userDecrypt(userTOKEN, src string) ([]byte, error) {
userBson, err := dbobj.lookupUserRecord(userTOKEN)
if userBson == nil || err != nil {
return nil, errors.New("not found")
}
if _, ok := userBson["key"]; !ok {
func (dbobj dbcon) userProfileDecrypt(userBSON map[string]interface{}) ([]byte, error) {
userKey, ok := userBSON["key"].(string)
if !ok {
// user might be deleted already
return nil, errors.New("not found")
}
userKeyBinary, err := base64.StdEncoding.DecodeString(userKey)
if err != nil {
return nil, err
}
data, ok := userBSON["data"].(string)
if !ok {
// user might be deleted already
return nil, errors.New("not found")
}
if len(data) == 0 {
return nil, errors.New("not found")
}
encData, err := base64.StdEncoding.DecodeString(data)
if err != nil {
return nil, err
}
if len(encData) == 0 {
return nil, errors.New("not found")
}
decrypted, err := utils.Decrypt(dbobj.masterKey, userKeyBinary, encData)
return decrypted, err
}
func (dbobj dbcon) userDecrypt(userBSON map[string]interface{}, src string) ([]byte, error) {
userKey, ok := userBSON["key"].(string)
if !ok {
// user might be deleted already
return nil, errors.New("not found")
}
userKey := userBson["key"].(string)
userKeyBinary, err := base64.StdEncoding.DecodeString(userKey)
if err != nil {
return nil, err
@@ -644,16 +580,8 @@ func (dbobj dbcon) userDecrypt(userTOKEN, src string) ([]byte, error) {
return decrypted, err
}
func (dbobj dbcon) userDecrypt2(userTOKEN, src string, src2 string) ([]byte, []byte, error) {
userBson, err := dbobj.lookupUserRecord(userTOKEN)
if userBson == nil || err != nil {
return nil, nil, errors.New("not found")
}
if _, ok := userBson["key"]; !ok {
// user might be deleted already
return nil, nil, errors.New("not found")
}
userKey := userBson["key"].(string)
func (dbobj dbcon) userDecrypt2(userBSON map[string]interface{}, src string, src2 string) ([]byte, []byte, error) {
userKey := userBSON["key"].(string)
userKeyBinary, err := base64.StdEncoding.DecodeString(userKey)
if err != nil {
return nil, nil, err

View File

@@ -118,7 +118,10 @@ func TestCreateUpdateUser(t *testing.T) {
t.Fatalf("Failed to get audit event/s\n")
}
records := raw["rows"].([]interface{})
if raw["total"].(float64) != 6 {
for num, r := range records {
log.Printf("audit record %d %v", num, r)
}
if raw["total"].(float64) != 8 {
t.Fatalf("Wrong number of audit event/s\n")
}
if len(records) != 1 {

View File

@@ -50,13 +50,12 @@ func (dbobj dbcon) createRootXtoken(customRootXtoken string) (string, error) {
return rootToken, nil
}
func (dbobj dbcon) generateUserLoginXtoken(userTOKEN string) (string, string, error) {
// check if user record exists
record, err := dbobj.lookupUserRecord(userTOKEN)
if record == nil || err != nil {
// not found
return "", "", errors.New("not found")
}
func (dbobj dbcon) genUserLoginXtoken(userTOKEN string) (string, string, error) {
// record, err := dbobj.lookupUserRecord(userTOKEN)
// if record == nil || err != nil {
// // not found
// return "", "", errors.New("not found")
// }
tokenUUID, err := uuid.GenerateUUID()
if err != nil {
return "", "", err

View File

@@ -101,7 +101,7 @@ func TestUserLoginDelete(t *testing.T) {
}
raw, _ = helpWithdrawAgreement("token", userTOKEN, "contract1")
if _, ok := raw["status"]; !ok || raw["status"].(string) != "ok" {
t.Fatalf("Failed to accept on consent")
t.Fatalf("Failed to withdraw on consent")
}
raw, _ = helpChangeUser("token", userTOKEN, `{"login":null}`)
if _, ok := raw["status"]; !ok || raw["status"].(string) != "ok" {