refactor code - adding new utils module

This commit is contained in:
yuli
2024-12-26 23:13:11 +02:00
parent e16ef588a7
commit 836f16d74d
26 changed files with 601 additions and 467 deletions

View File

@@ -7,6 +7,7 @@ import (
"reflect"
"github.com/julienschmidt/httprouter"
"github.com/securitybunker/databunker/src/utils"
//"go.mongodb.org/mongo-driver/bson"
)
@@ -17,42 +18,42 @@ func (e mainEnv) agreementAccept(w http.ResponseWriter, r *http.Request, ps http
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)
if utils.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)
brief = utils.NormalizeBrief(brief)
if utils.CheckValidBrief(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)
ReturnError(w, r, "internal error", 405, err, event)
return
}
if exists == false {
returnError(w, r, "not found", 404, nil, event)
ReturnError(w, r, "not found", 404, nil, event)
return
}
userTOKEN := ""
if mode == "token" {
if enforceUUID(w, identity, event) == false {
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)
ReturnError(w, r, "internal error", 405, err, event)
return
}
if e.enforceAuth(w, r, event) == "" {
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)
ReturnError(w, r, "internal error", 405, err, event)
return
}
if userBson != nil {
@@ -60,33 +61,33 @@ func (e mainEnv) agreementAccept(w http.ResponseWriter, r *http.Request, ps http
event.Record = userTOKEN
} else {
if mode == "login" {
returnError(w, r, "internal error", 405, nil, event)
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)
records, err := utils.GetJSONPostMap(r)
if err != nil {
returnError(w, r, "failed to decode request body", 405, err, event)
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"])
referencecode := utils.GetStringValue(records["referencecode"])
lastmodifiedby := utils.GetStringValue(records["lastmodifiedby"])
agreementmethod := utils.GetStringValue(records["agreementmethod"])
status := utils.GetStringValue(records["status"])
if len(status) == 0 {
status = "yes"
} else {
status = normalizeConsentStatus(status)
status = utils.NormalizeConsentStatus(status)
}
if value, ok := records["expiration"]; ok {
switch records["expiration"].(type) {
case string:
expiration, _ = parseExpiration(value.(string))
expiration, _ = utils.ParseExpiration(value.(string))
case float64:
expiration = int32(value.(float64))
}
@@ -94,16 +95,16 @@ func (e mainEnv) agreementAccept(w http.ResponseWriter, r *http.Request, ps http
if value, ok := records["starttime"]; ok {
switch records["starttime"].(type) {
case string:
starttime, _ = parseExpiration(value.(string))
starttime, _ = utils.ParseExpiration(value.(string))
case float64:
starttime = int32(value.(float64))
}
}
switch mode {
case "email":
identity = normalizeEmail(identity)
identity = utils.NormalizeEmail(identity)
case "phone":
identity = normalizePhone(identity, e.conf.Sms.DefaultCountry)
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,
@@ -131,37 +132,37 @@ func (e mainEnv) agreementWithdraw(w http.ResponseWriter, r *http.Request, ps ht
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)
if utils.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)
brief = utils.NormalizeBrief(brief)
if utils.CheckValidBrief(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)
ReturnError(w, r, "internal error", 405, err, event)
return
}
if lbasis == nil {
returnError(w, r, "not found", 405, nil, event)
ReturnError(w, r, "not found", 405, nil, event)
return
}
userTOKEN := ""
authResult := ""
if mode == "token" {
if enforceUUID(w, identity, event) == false {
if EnforceUUID(w, identity, event) == false {
return
}
userBson, _ := e.db.lookupUserRecord(identity)
if userBson == nil {
returnError(w, r, "internal error", 405, nil, event)
ReturnError(w, r, "internal error", 405, nil, event)
return
}
authResult = e.enforceAuth(w, r, event)
authResult = e.EnforceAuth(w, r, event)
if authResult == "" {
return
}
@@ -174,18 +175,18 @@ func (e mainEnv) agreementWithdraw(w http.ResponseWriter, r *http.Request, ps ht
event.Record = userTOKEN
} else {
if mode == "login" {
returnError(w, r, "internal error", 405, nil, event)
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)
records, err := utils.GetJSONPostMap(r)
if err != nil {
returnError(w, r, "failed to decode request body", 405, err, event)
ReturnError(w, r, "failed to decode request body", 405, err, event)
return
}
lastmodifiedby := getStringValue(records["lastmodifiedby"])
lastmodifiedby := utils.GetStringValue(records["lastmodifiedby"])
selfService := false
if value, ok := lbasis["usercontrol"]; ok {
if reflect.TypeOf(value).Kind() == reflect.Bool {
@@ -200,7 +201,7 @@ func (e mainEnv) agreementWithdraw(w http.ResponseWriter, r *http.Request, ps ht
if selfService == false {
// user can change consent only for briefs defined in self-service
if len(authResult) == 0 {
if e.enforceAdmin(w, r, event) == "" {
if e.EnforceAdmin(w, r, event) == "" {
return
}
}
@@ -209,7 +210,7 @@ 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)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
@@ -219,9 +220,9 @@ func (e mainEnv) agreementWithdraw(w http.ResponseWriter, r *http.Request, ps ht
}
switch mode {
case "email":
identity = normalizeEmail(identity)
identity = utils.NormalizeEmail(identity)
case "phone":
identity = normalizePhone(identity, e.conf.Sms.DefaultCountry)
identity = utils.NormalizePhone(identity, e.conf.Sms.DefaultCountry)
}
e.db.withdrawAgreement(userTOKEN, brief, mode, identity, lastmodifiedby)
w.Header().Set("Content-Type", "application/json; charset=utf-8")
@@ -237,21 +238,21 @@ 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")
if e.enforceAdmin(w, r, nil) == "" {
if e.EnforceAdmin(w, r, nil) == "" {
return
}
brief = normalizeBrief(brief)
if isValidBrief(brief) == false {
returnError(w, r, "bad brief format", 405, nil, nil)
brief = utils.NormalizeBrief(brief)
if utils.CheckValidBrief(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)
ReturnError(w, r, "internal error", 405, nil, nil)
return
}
if exists == false {
returnError(w, r, "not found", 405, nil, nil)
ReturnError(w, r, "not found", 405, nil, nil)
return
}
e.db.revokeLegalBasis(brief)
@@ -266,22 +267,22 @@ func (e mainEnv) getUserAgreements(w http.ResponseWriter, r *http.Request, ps ht
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)
if utils.ValidateMode(mode) == false {
ReturnError(w, r, "bad mode", 405, nil, event)
return
}
userTOKEN := ""
if mode == "token" {
if enforceUUID(w, identity, event) == false {
if EnforceUUID(w, identity, event) == false {
return
}
userBson, _ := e.db.lookupUserRecord(identity)
if userBson == nil {
returnError(w, r, "internal error", 405, nil, event)
ReturnError(w, r, "internal error", 405, nil, event)
return
}
if e.enforceAuth(w, r, event) == "" {
if e.EnforceAuth(w, r, event) == "" {
return
}
userTOKEN = identity
@@ -291,12 +292,12 @@ func (e mainEnv) getUserAgreements(w http.ResponseWriter, r *http.Request, ps ht
if userBson != nil {
userTOKEN = userBson["token"].(string)
event.Record = userTOKEN
if e.enforceAuth(w, r, event) == "" {
if e.EnforceAuth(w, r, event) == "" {
return
}
} else {
if mode == "login" {
returnError(w, r, "internal error", 405, nil, event)
ReturnError(w, r, "internal error", 405, nil, event)
return
}
// else user not found - we allow to save consent for unlinked users!
@@ -304,7 +305,7 @@ func (e mainEnv) getUserAgreements(w http.ResponseWriter, r *http.Request, ps ht
}
}
// make sure that user is logged in here, unless he wants to cancel emails
if e.enforceAuth(w, r, event) == "" {
if e.EnforceAuth(w, r, event) == "" {
return
}
var resultJSON []byte
@@ -316,7 +317,7 @@ func (e mainEnv) getUserAgreements(w http.ResponseWriter, r *http.Request, ps ht
resultJSON, numRecords, err = e.db.listAgreementRecordsByIdentity(identity)
}
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
@@ -332,35 +333,35 @@ func (e mainEnv) getUserAgreement(w http.ResponseWriter, r *http.Request, ps htt
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)
if utils.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)
brief = utils.NormalizeBrief(brief)
if utils.CheckValidBrief(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)
ReturnError(w, r, "internal error", 405, err, event)
return
}
if exists == false {
returnError(w, r, "not found", 404, nil, event)
ReturnError(w, r, "not found", 404, nil, event)
return
}
userTOKEN := ""
if mode == "token" {
if enforceUUID(w, identity, event) == false {
if EnforceUUID(w, identity, event) == false {
return
}
userBson, _ := e.db.lookupUserRecord(identity)
if userBson == nil {
returnError(w, r, "internal error", 405, nil, event)
ReturnError(w, r, "internal error", 405, nil, event)
return
}
if e.enforceAuth(w, r, event) == "" {
if e.EnforceAuth(w, r, event) == "" {
return
}
userTOKEN = identity
@@ -370,29 +371,29 @@ func (e mainEnv) getUserAgreement(w http.ResponseWriter, r *http.Request, ps htt
if userBson != nil {
userTOKEN = userBson["token"].(string)
event.Record = userTOKEN
if e.enforceAuth(w, r, event) == "" {
if e.EnforceAuth(w, r, event) == "" {
return
}
} else {
if mode == "login" {
returnError(w, r, "internal error", 405, nil, event)
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) == "" {
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)
ReturnError(w, r, "internal error", 405, err, event)
return
}
if resultJSON == nil {
returnError(w, r, "not found", 405, err, event)
ReturnError(w, r, "not found", 405, err, event)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
@@ -409,19 +410,19 @@ func (e mainEnv) consentUserRecord(w http.ResponseWriter, r *http.Request, ps ht
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)
if utils.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)
brief = utils.NormalizeBrief(brief)
if utils.CheckValidBrief(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 {
if EnforceUUID(w, identity, event) == false {
return
}
userBson, _ = e.db.lookupUserRecord(identity)
@@ -433,20 +434,20 @@ func (e mainEnv) consentUserRecord(w http.ResponseWriter, r *http.Request, ps ht
}
}
if userBson == nil {
returnError(w, r, "internal error", 405, nil, event)
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) == "" {
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)
ReturnError(w, r, "internal error", 405, err, event)
return
}
if resultJSON == nil {
returnError(w, r, "not found", 405, nil, event)
ReturnError(w, r, "not found", 405, nil, event)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
@@ -461,7 +462,7 @@ func (e mainEnv) consentFilterRecords(w http.ResponseWriter, r *http.Request, ps
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) == "" {
if e.EnforceAuth(w, r, event) == "" {
return
}
var offset int32
@@ -475,7 +476,7 @@ func (e mainEnv) consentFilterRecords(w http.ResponseWriter, r *http.Request, ps
}
resultJSON, numRecords, err := e.db.filterConsentRecords(brief, offset, limit)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
log.Printf("Total count of rows: %d\n", numRecords)

View File

@@ -6,30 +6,122 @@ import (
"net/http"
"github.com/julienschmidt/httprouter"
"github.com/securitybunker/databunker/src/utils"
)
func ReturnError(w http.ResponseWriter, r *http.Request, message string, code int, err error, event *auditEvent) {
log.Printf("[%d] %s %s -> Return error\n", code, r.Method, r.URL.Path)
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(code)
fmt.Fprintf(w, `{"status":"error","message":%q}`, message)
if event != nil {
event.Status = "error"
event.Msg = message
if err != nil {
event.Debug = err.Error()
log.Printf("Generate error response: %s, Error: %s\n", message, err.Error())
} else {
log.Printf("Generate error response: %s\n", message)
}
}
//http.Error(w, http.StatusText(405), 405)
}
func EnforceUUID(w http.ResponseWriter, uuidCode string, event *auditEvent) bool {
if utils.CheckValidUUID(uuidCode) == false {
//fmt.Printf("405 bad uuid in : %s\n", uuidCode)
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(405)
fmt.Fprintf(w, `{"status":"error","message":"bad uuid"}`)
if event != nil {
event.Status = "error"
event.Msg = "bad uuid"
}
return false
}
return true
}
func (e mainEnv) EnforceAuth(w http.ResponseWriter, r *http.Request, event *auditEvent) string {
/*
for key, value := range r.Header {
fmt.Printf("%s => %s\n", key, value)
}
*/
if token, ok := r.Header["X-Bunker-Token"]; ok {
authResult, err := e.db.checkUserAuthXToken(token[0])
//fmt.Printf("error in auth? error %s - %s\n", err, token[0])
if err == nil {
if event != nil {
event.Identity = authResult.name
if authResult.ttype == "login" && authResult.token == event.Record {
return authResult.ttype
}
}
if len(authResult.ttype) > 0 && authResult.ttype != "login" {
return authResult.ttype
}
}
/*
if e.db.checkXtoken(token[0]) == true {
if event != nil {
event.Identity = "admin"
}
return true
}
*/
}
log.Printf("403 Access denied\n")
w.WriteHeader(http.StatusForbidden)
w.Write([]byte("Access denied"))
if event != nil {
event.Status = "error"
event.Msg = "access denied"
}
return ""
}
func (e mainEnv) EnforceAdmin(w http.ResponseWriter, r *http.Request, event *auditEvent) string {
if token, ok := r.Header["X-Bunker-Token"]; ok {
authResult, err := e.db.checkUserAuthXToken(token[0])
//fmt.Printf("error in auth? error %s - %s\n", err, token[0])
if err == nil {
if event != nil {
event.Identity = authResult.name
}
if len(authResult.ttype) > 0 && authResult.ttype != "login" {
return authResult.ttype
}
}
}
log.Printf("403 Access denied\n")
w.WriteHeader(http.StatusForbidden)
w.Write([]byte("Access denied"))
return ""
}
func (e mainEnv) getAuditEvents(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
userTOKEN := ps.ByName("token")
event := audit("view audit events", userTOKEN, "token", userTOKEN)
defer func() { event.submit(e.db, e.conf) }()
if enforceUUID(w, userTOKEN, event) == false {
if EnforceUUID(w, userTOKEN, event) == false {
return
}
if e.enforceAuth(w, r, event) == "" {
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])
offset = utils.Atoi(value[0])
}
if value, ok := args["limit"]; ok {
limit = atoi(value[0])
limit = utils.Atoi(value[0])
}
resultJSON, counter, err := e.db.getAuditEvents(userTOKEN, offset, limit)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
//fmt.Printf("Total count of events: %d\n", counter)
@@ -40,21 +132,21 @@ func (e mainEnv) getAuditEvents(w http.ResponseWriter, r *http.Request, ps httpr
}
func (e mainEnv) getAdminAuditEvents(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
if e.enforceAdmin(w, r, nil) == "" {
if e.EnforceAdmin(w, r, nil) == "" {
return
}
var offset int32
var limit int32 = 10
args := r.URL.Query()
if value, ok := args["offset"]; ok {
offset = atoi(value[0])
offset = utils.Atoi(value[0])
}
if value, ok := args["limit"]; ok {
limit = atoi(value[0])
limit = utils.Atoi(value[0])
}
resultJSON, counter, err := e.db.getAdminAuditEvents(offset, limit)
if err != nil {
returnError(w, r, "internal error", 405, err, nil)
ReturnError(w, r, "internal error", 405, err, nil)
return
}
//fmt.Printf("Total count of events: %d\n", counter)
@@ -69,17 +161,17 @@ func (e mainEnv) getAuditEvent(w http.ResponseWriter, r *http.Request, ps httpro
event := audit("view audit event", atoken, "token", atoken)
defer func() { event.submit(e.db, e.conf) }()
//fmt.Println("error code")
if enforceUUID(w, atoken, event) == false {
if EnforceUUID(w, atoken, event) == false {
return
}
userTOKEN, resultJSON, err := e.db.getAuditEvent(atoken)
log.Printf("extracted user token: %s", userTOKEN)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
event.Record = userTOKEN
if e.enforceAuth(w, r, event) == "" {
if e.EnforceAuth(w, r, event) == "" {
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")

View File

@@ -9,16 +9,20 @@ import (
"log"
"math/rand"
"net/http"
"os"
"strings"
"time"
"github.com/gobuffalo/packr"
"github.com/julienschmidt/httprouter"
"github.com/kelseyhightower/envconfig"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"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"
)
var version string
@@ -105,16 +109,6 @@ type mainEnv struct {
stopChan chan struct{}
}
// userJSON used to parse user POST
type userJSON struct {
jsonData []byte
loginIdx string
emailIdx string
phoneIdx string
customIdx string
token string
}
type tokenAuthResult struct {
ttype string
name string
@@ -151,7 +145,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.EnforceAuth(w, r, nil) == "" {
return
}
w.WriteHeader(200)
@@ -169,6 +163,33 @@ func (e mainEnv) checkStatus(w http.ResponseWriter, r *http.Request, ps httprout
}
}
// ReadConfFile() read configuration file.
func ReadConfFile(cfg *Config, filepath *string) error {
confFile := "databunker.yaml"
if filepath != nil {
if len(*filepath) > 0 {
confFile = *filepath
}
}
log.Printf("Loading configuration file: %s\n", confFile)
f, err := os.Open(confFile)
if err != nil {
return err
}
decoder := yaml.NewDecoder(f)
err = decoder.Decode(cfg)
if err != nil {
return err
}
return nil
}
// readEnv() process environment variables.
func ReadEnv(cfg *Config) error {
err := envconfig.Process("", cfg)
return err
}
// setupRouter() setup HTTP Router object.
func (e mainEnv) setupRouter() *httprouter.Router {
box := packr.NewBox("../ui")
@@ -335,7 +356,7 @@ func (e mainEnv) setupRouter() *httprouter.Router {
// dbCleanup() is used to run cron jobs.
func (e mainEnv) dbCleanupDo() {
log.Printf("db cleanup timeout\n")
exp, _ := parseExpiration0(e.conf.Policy.MaxAuditRetentionPeriod)
exp, _ := utils.ParseExpiration0(e.conf.Policy.MaxAuditRetentionPeriod)
if exp > 0 {
e.db.store.DeleteExpired0(storage.TblName.Audit, exp)
}
@@ -364,13 +385,13 @@ 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 *auditEvent) string {
var err error
if validateMode(mode) == false {
returnError(w, r, "bad mode", 405, nil, event)
if utils.ValidateMode(mode) == false {
ReturnError(w, r, "bad mode", 405, nil, event)
return ""
}
var userBson bson.M
if mode == "token" {
if enforceUUID(w, identity, event) == false {
if EnforceUUID(w, identity, event) == false {
return ""
}
userBson, err = e.db.lookupUserRecord(identity)
@@ -378,7 +399,7 @@ func (e mainEnv) loadUserToken(w http.ResponseWriter, r *http.Request, mode stri
userBson, err = e.db.lookupUserRecordByIndex(mode, identity, e.conf)
}
if userBson == nil || err != nil {
returnError(w, r, "internal error", 405, nil, event)
ReturnError(w, r, "internal error", 405, nil, event)
return ""
}
event.Record = userBson["token"].(string)
@@ -470,6 +491,6 @@ func (e mainEnv) reqMiddleware(handler http.Handler) http.Handler {
// main application function
func main() {
rand.Seed(time.Now().UnixNano())
lockMemory()
utils.LockMemory()
loadService()
}

View File

@@ -6,14 +6,16 @@ import (
"encoding/hex"
"errors"
"fmt"
"github.com/afocus/captcha"
"github.com/gobuffalo/packr"
"github.com/julienschmidt/httprouter"
"image/png"
"log"
"net/http"
"regexp"
"time"
"github.com/afocus/captcha"
"github.com/gobuffalo/packr"
"github.com/julienschmidt/httprouter"
"github.com/securitybunker/databunker/src/utils"
)
var (
@@ -26,19 +28,19 @@ func (e mainEnv) showCaptcha(w http.ResponseWriter, r *http.Request, ps httprout
code := ps.ByName("code")
if len(code) == 0 {
err := errors.New("Bad code")
returnError(w, r, "bad code", 405, err, nil)
ReturnError(w, r, "bad code", 405, err, nil)
return
}
s, err := decryptCaptcha(code)
if err != nil {
returnError(w, r, err.Error(), 405, err, nil)
ReturnError(w, r, err.Error(), 405, err, nil)
return
}
log.Printf("Decoded captcha: %s", s)
//box := packr.NewBox("../ui")
//comic, err := box.Find("site/fonts/comic.ttf")
//if err != nil {
// returnError(w, r, err.Error(), 405, err, nil)
// ReturnError(w, r, err.Error(), 405, err, nil)
// return
//}
cap := captcha.New()
@@ -62,7 +64,7 @@ func initCaptcha(h [16]byte) {
}
func generateCaptcha() (string, error) {
code := randNum(6)
code := utils.RandNum(6)
//log.Printf("Generate captcha code: %d", code)
now := int32(time.Now().Unix())
s := fmt.Sprintf("%d:%d", code, now)
@@ -112,7 +114,7 @@ func decryptCaptcha(data string) (string, error) {
return "", errors.New("Failed to parse captcha")
}
code := match[1]
t := atoi(match[2])
t := utils.Atoi(match[2])
// check if time expired
now := int32(time.Now().Unix())
if now > (t + 120) {

View File

@@ -23,7 +23,7 @@ func (e mainEnv) initContext(r *http.Request) {
func (e mainEnv) cookieSettings(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
resultJSON, scriptsJSON, _, err := e.db.getLegalBasisCookieConf()
if err != nil {
returnError(w, r, "internal error", 405, err, nil)
ReturnError(w, r, "internal error", 405, err, nil)
return
}
resultUIConfJSON, _ := json.Marshal(e.conf.UI)
@@ -34,7 +34,7 @@ func (e mainEnv) cookieSettings(w http.ResponseWriter, r *http.Request, ps httpr
}
func (e mainEnv) configurationDump(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
if e.enforceAuth(w, r, nil) == "" {
if e.EnforceAuth(w, r, nil) == "" {
return
}
resultJSON, _ := json.Marshal(e.conf)

View File

@@ -7,6 +7,7 @@ import (
uuid "github.com/hashicorp/go-uuid"
"github.com/julienschmidt/httprouter"
"github.com/securitybunker/databunker/src/storage"
"github.com/securitybunker/databunker/src/utils"
"go.mongodb.org/mongo-driver/bson"
)
@@ -16,7 +17,7 @@ func (e mainEnv) expUsers() error {
userTOKEN := rec["token"].(string)
resultJSON, userBSON, _ := e.db.getUser(userTOKEN)
if resultJSON != nil {
email := getStringValue(userBSON["email"])
email := utils.GetStringValue(userBSON["email"])
if len(email) > 0 {
e.globalUserDelete(email)
}
@@ -33,13 +34,13 @@ func (e mainEnv) expGetStatus(w http.ResponseWriter, r *http.Request, ps httprou
event := audit("get expiration status by "+mode, identity, mode, identity)
defer func() { event.submit(e.db, e.conf) }()
var err error
if validateMode(mode) == false {
returnError(w, r, "bad mode", 405, nil, event)
if utils.ValidateMode(mode) == false {
ReturnError(w, r, "bad mode", 405, nil, event)
return
}
var userBson bson.M
if mode == "token" {
if enforceUUID(w, identity, event) == false {
if EnforceUUID(w, identity, event) == false {
return
}
userBson, err = e.db.lookupUserRecord(identity)
@@ -47,14 +48,14 @@ func (e mainEnv) expGetStatus(w http.ResponseWriter, r *http.Request, ps httprou
userBson, err = e.db.lookupUserRecordByIndex(mode, identity, e.conf)
}
if userBson == nil || err != nil {
returnError(w, r, "internal error", 405, nil, event)
ReturnError(w, r, "internal error", 405, nil, event)
return
}
userTOKEN := userBson["token"].(string)
event.Record = userTOKEN
expirationDate := getIntValue(userBson["endtime"])
expirationStatus := getStringValue(userBson["expstatus"])
expirationToken := 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")
@@ -68,14 +69,14 @@ func (e mainEnv) expCancel(w http.ResponseWriter, r *http.Request, ps httprouter
mode := ps.ByName("mode")
event := audit("clear user expiration by "+mode, identity, mode, identity)
defer func() { event.submit(e.db, e.conf) }()
if validateMode(mode) == false {
returnError(w, r, "bad mode", 405, nil, event)
if utils.ValidateMode(mode) == false {
ReturnError(w, r, "bad mode", 405, nil, event)
return
}
userTOKEN := identity
var userBson bson.M
if mode == "token" {
if enforceUUID(w, identity, event) == false {
if EnforceUUID(w, identity, event) == false {
return
}
userBson, err = e.db.lookupUserRecord(identity)
@@ -87,13 +88,13 @@ func (e mainEnv) expCancel(w http.ResponseWriter, r *http.Request, ps httprouter
}
}
if userBson == nil || err != nil {
returnError(w, r, "internal error", 405, nil, event)
ReturnError(w, r, "internal error", 405, nil, event)
return
}
status := ""
err = e.db.updateUserExpStatus(userTOKEN, status)
if err != nil {
returnError(w, r, "internal error", 405, nil, event)
ReturnError(w, r, "internal error", 405, nil, event)
return
}
finalJSON := `{"status":"ok"}`
@@ -107,12 +108,12 @@ func (e mainEnv) expRetainData(w http.ResponseWriter, r *http.Request, ps httpro
mode := "exptoken"
event := audit("retain user data by exptoken", identity, mode, identity)
defer func() { event.submit(e.db, e.conf) }()
if enforceUUID(w, identity, event) == false {
if EnforceUUID(w, identity, event) == false {
return
}
userBson, err := e.db.lookupUserRecordByIndex(mode, identity, e.conf)
if userBson == nil || err != nil {
returnError(w, r, "internal error", 405, nil, event)
ReturnError(w, r, "internal error", 405, nil, event)
return
}
userTOKEN := userBson["token"].(string)
@@ -120,7 +121,7 @@ func (e mainEnv) expRetainData(w http.ResponseWriter, r *http.Request, ps httpro
status := "retain"
err = e.db.updateUserExpStatus(userTOKEN, status)
if err != nil {
returnError(w, r, "internal error", 405, nil, event)
ReturnError(w, r, "internal error", 405, nil, event)
return
}
w.WriteHeader(200)
@@ -132,22 +133,22 @@ func (e mainEnv) expDeleteData(w http.ResponseWriter, r *http.Request, ps httpro
mode := "exptoken"
event := audit("delete user data by exptoken", identity, mode, identity)
defer func() { event.submit(e.db, e.conf) }()
if enforceUUID(w, identity, event) == false {
if EnforceUUID(w, identity, event) == false {
return
}
userJSON, userTOKEN, userBSON, err := e.db.getUserByIndex(identity, mode, e.conf)
if userJSON == nil || err != nil {
returnError(w, r, "internal error", 405, nil, event)
ReturnError(w, r, "internal error", 405, nil, event)
return
}
event.Record = userTOKEN
email := getStringValue(userBSON["email"])
email := utils.GetStringValue(userBSON["email"])
if len(email) > 0 {
e.globalUserDelete(email)
}
_, err = e.db.deleteUserRecord(userJSON, userTOKEN, e.conf)
if err != nil {
returnError(w, r, "internal error", 405, nil, event)
ReturnError(w, r, "internal error", 405, nil, event)
return
}
e.db.updateUserExpStatus(userTOKEN, "expired")
@@ -162,32 +163,32 @@ func (e mainEnv) expStart(w http.ResponseWriter, r *http.Request, ps httprouter.
event := audit("initiate user record expiration by "+mode, identity, mode, identity)
defer func() { event.submit(e.db, e.conf) }()
if e.enforceAdmin(w, r, event) == "" {
if e.EnforceAdmin(w, r, event) == "" {
return
}
userTOKEN := e.loadUserToken(w, r, mode, identity, event)
if userTOKEN == "" {
return
}
records, err := getJSONPostMap(r)
records, err := utils.GetJSONPostMap(r)
if err != nil {
returnError(w, r, "failed to decode request body", 405, err, event)
ReturnError(w, r, "failed to decode request body", 405, err, event)
return
}
expirationStr := getStringValue(records["expiration"])
expiration := setExpiration(e.conf.Policy.MaxUserRetentionPeriod, expirationStr)
endtime, _ := parseExpiration(expiration)
status := getStringValue(records["status"])
expirationStr := utils.GetStringValue(records["expiration"])
expiration := utils.SetExpiration(e.conf.Policy.MaxUserRetentionPeriod, expirationStr)
endtime, _ := utils.ParseExpiration(expiration)
status := utils.GetStringValue(records["status"])
if len(status) == 0 {
status = "wait"
}
expToken, err := uuid.GenerateUUID()
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
}
err = e.db.initiateUserExpiration(userTOKEN, endtime, status, expToken)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
finalJSON := fmt.Sprintf(`{"status":"ok","exptoken":"%s"}`, expToken)

View File

@@ -6,6 +6,8 @@ toolchain go1.23.3
replace github.com/securitybunker/databunker/src/storage => ./storage
replace github.com/securitybunker/databunker/src/utils => ./utils
require (
github.com/afocus/captcha v0.0.0-20191010092841-4bd1f21c8868
github.com/evanphx/json-patch v5.9.0+incompatible
@@ -50,13 +52,14 @@ require (
github.com/prometheus/procfs v0.15.1 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rogpeppe/go-internal v1.13.1 // indirect
github.com/securitybunker/databunker/src/utils v0.0.0-20241226201542-d0c5d1a19645 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 // indirect
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 // indirect
golang.org/x/image v0.23.0 // indirect
golang.org/x/mod v0.22.0 // indirect
google.golang.org/protobuf v1.36.0 // indirect
google.golang.org/protobuf v1.36.1 // indirect
modernc.org/gc/v3 v3.0.0-20241213165251-3bc300f6d0c9 // indirect
modernc.org/libc v1.61.4 // indirect
modernc.org/mathutil v1.6.0 // indirect

View File

@@ -16,7 +16,7 @@ func init() {
rootToken = myRootToken
var cfg Config
cfile := "../databunker.yaml"
err = readConfFile(&cfg, &cfile)
err = ReadConfFile(&cfg, &cfile)
cfg.SelfService.AppRecordChange = []string{"testapp", "super"}
if err != nil {
cfg.SelfService.ForgetMe = false

View File

@@ -7,37 +7,38 @@ import (
"reflect"
"github.com/julienschmidt/httprouter"
"github.com/securitybunker/databunker/src/utils"
//"go.mongodb.org/mongo-driver/bson"
)
func (e mainEnv) createLegalBasis(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
brief := ps.ByName("brief")
if e.enforceAdmin(w, r, nil) == "" {
if e.EnforceAdmin(w, r, nil) == "" {
return
}
brief = normalizeBrief(brief)
if isValidBrief(brief) == false {
returnError(w, r, "bad brief format", 405, nil, nil)
brief = utils.NormalizeBrief(brief)
if utils.CheckValidBrief(brief) == false {
ReturnError(w, r, "bad brief format", 405, nil, nil)
return
}
records, err := getJSONPostMap(r)
records, err := utils.GetJSONPostMap(r)
if err != nil {
returnError(w, r, "failed to decode request body", 405, err, nil)
ReturnError(w, r, "failed to decode request body", 405, err, nil)
return
}
newbrief := getStringValue(records["brief"])
newbrief := utils.GetStringValue(records["brief"])
if len(newbrief) > 0 && newbrief != brief {
if isValidBrief(newbrief) == false {
returnError(w, r, "bad brief format", 405, nil, nil)
if utils.CheckValidBrief(newbrief) == false {
ReturnError(w, r, "bad brief format", 405, nil, nil)
return
}
}
status := getStringValue(records["status"])
module := getStringValue(records["module"])
fulldesc := getStringValue(records["fulldesc"])
shortdesc := getStringValue(records["shortdesc"])
basistype := getStringValue(records["basistype"])
requiredmsg := getStringValue(records["requiredmsg"])
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"])
usercontrol := false
requiredflag := false
if status != "disabled" {
@@ -82,12 +83,12 @@ func (e mainEnv) createLegalBasis(w http.ResponseWriter, r *http.Request, ps htt
func (e mainEnv) deleteLegalBasis(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
brief := ps.ByName("brief")
if e.enforceAdmin(w, r, nil) == "" {
if e.EnforceAdmin(w, r, nil) == "" {
return
}
brief = normalizeBrief(brief)
if isValidBrief(brief) == false {
returnError(w, r, "bad brief format", 405, nil, nil)
brief = utils.NormalizeBrief(brief)
if utils.CheckValidBrief(brief) == false {
ReturnError(w, r, "bad brief format", 405, nil, nil)
return
}
e.db.unlinkProcessingActivityBrief(brief)
@@ -98,12 +99,12 @@ func (e mainEnv) deleteLegalBasis(w http.ResponseWriter, r *http.Request, ps htt
}
func (e mainEnv) listLegalBasisRecords(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
if e.enforceAdmin(w, r, nil) == "" {
if e.EnforceAdmin(w, r, nil) == "" {
return
}
resultJSON, numRecords, err := e.db.getLegalBasisRecords()
if err != nil {
returnError(w, r, "internal error", 405, err, nil)
ReturnError(w, r, "internal error", 405, err, nil)
return
}
log.Printf("Total count of rows: %d\n", numRecords)

View File

@@ -7,22 +7,23 @@ import (
"reflect"
"github.com/julienschmidt/httprouter"
"github.com/securitybunker/databunker/src/utils"
//"go.mongodb.org/mongo-driver/bson"
)
func (e mainEnv) pactivityCreate(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
activity := ps.ByName("activity")
if e.enforceAdmin(w, r, nil) == "" {
if e.EnforceAdmin(w, r, nil) == "" {
return
}
activity = normalizeBrief(activity)
if isValidBrief(activity) == false {
returnError(w, r, "bad activity format", 405, nil, nil)
activity = utils.NormalizeBrief(activity)
if utils.CheckValidBrief(activity) == false {
ReturnError(w, r, "bad activity format", 405, nil, nil)
return
}
records, err := getJSONPostMap(r)
records, err := utils.GetJSONPostMap(r)
if err != nil {
returnError(w, r, "failed to decode request body", 405, err, nil)
ReturnError(w, r, "failed to decode request body", 405, err, nil)
return
}
defer func() {
@@ -70,12 +71,12 @@ func (e mainEnv) pactivityCreate(w http.ResponseWriter, r *http.Request, ps http
func (e mainEnv) pactivityDelete(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
activity := ps.ByName("activity")
if e.enforceAdmin(w, r, nil) == "" {
if e.EnforceAdmin(w, r, nil) == "" {
return
}
activity = normalizeBrief(activity)
if isValidBrief(activity) == false {
returnError(w, r, "bad activity format", 405, nil, nil)
activity = utils.NormalizeBrief(activity)
if utils.CheckValidBrief(activity) == false {
ReturnError(w, r, "bad activity format", 405, nil, nil)
return
}
e.db.deleteProcessingActivity(activity)
@@ -87,31 +88,31 @@ func (e mainEnv) pactivityDelete(w http.ResponseWriter, r *http.Request, ps http
func (e mainEnv) pactivityLink(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
activity := ps.ByName("activity")
brief := ps.ByName("brief")
if e.enforceAdmin(w, r, nil) == "" {
if e.EnforceAdmin(w, r, nil) == "" {
return
}
activity = normalizeBrief(activity)
if isValidBrief(activity) == false {
returnError(w, r, "bad activity format", 405, nil, nil)
activity = utils.NormalizeBrief(activity)
if utils.CheckValidBrief(activity) == false {
ReturnError(w, r, "bad activity format", 405, nil, nil)
return
}
brief = normalizeBrief(brief)
if isValidBrief(brief) == false {
returnError(w, r, "bad brief format", 405, nil, nil)
brief = utils.NormalizeBrief(brief)
if utils.CheckValidBrief(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)
ReturnError(w, r, "internal error", 405, nil, nil)
return
}
if exists == false {
returnError(w, r, "not found", 405, nil, nil)
ReturnError(w, r, "not found", 405, nil, nil)
return
}
_, err = e.db.linkProcessingActivity(activity, brief)
if err != nil {
returnError(w, r, "internal error", 405, err, nil)
ReturnError(w, r, "internal error", 405, err, nil)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
@@ -122,22 +123,22 @@ func (e mainEnv) pactivityLink(w http.ResponseWriter, r *http.Request, ps httpro
func (e mainEnv) pactivityUnlink(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
activity := ps.ByName("activity")
brief := ps.ByName("brief")
if e.enforceAdmin(w, r, nil) == "" {
if e.EnforceAdmin(w, r, nil) == "" {
return
}
activity = normalizeBrief(activity)
if isValidBrief(activity) == false {
returnError(w, r, "bad activity format", 405, nil, nil)
activity = utils.NormalizeBrief(activity)
if utils.CheckValidBrief(activity) == false {
ReturnError(w, r, "bad activity format", 405, nil, nil)
return
}
brief = normalizeBrief(brief)
if isValidBrief(brief) == false {
returnError(w, r, "bad brief format", 405, nil, nil)
brief = utils.NormalizeBrief(brief)
if utils.CheckValidBrief(brief) == false {
ReturnError(w, r, "bad brief format", 405, nil, nil)
return
}
_, err := e.db.unlinkProcessingActivity(activity, brief)
if err != nil {
returnError(w, r, "internal error", 405, err, nil)
ReturnError(w, r, "internal error", 405, err, nil)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
@@ -146,12 +147,12 @@ func (e mainEnv) pactivityUnlink(w http.ResponseWriter, r *http.Request, ps http
}
func (e mainEnv) pactivityList(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
if e.enforceAdmin(w, r, nil) == "" {
if e.EnforceAdmin(w, r, nil) == "" {
return
}
resultJSON, numRecords, err := e.db.listProcessingActivities()
if err != nil {
returnError(w, r, "internal error", 405, err, nil)
ReturnError(w, r, "internal error", 405, err, nil)
return
}
log.Printf("Total count of rows: %d\n", numRecords)

View File

@@ -9,6 +9,7 @@ import (
"time"
"github.com/securitybunker/databunker/src/storage"
"github.com/securitybunker/databunker/src/utils"
"go.mongodb.org/mongo-driver/bson"
)
@@ -75,7 +76,7 @@ func (dbobj dbcon) linkProcessingActivity(activity string, brief string) (bool,
}
}
briefs := strings.Split(legalbasis, ",")
if contains(briefs, brief) == true {
if utils.SliceContains(briefs, brief) == true {
// nothing to do here
return false, nil
}
@@ -106,7 +107,7 @@ func (dbobj dbcon) unlinkProcessingActivity(activity string, brief string) (bool
}
}
briefs := strings.Split(legalbasis, ",")
if contains(briefs, brief) == false {
if utils.SliceContains(briefs, brief) == false {
// nothing to do here
return false, nil
}

View File

@@ -7,11 +7,12 @@ import (
"strings"
"github.com/julienschmidt/httprouter"
"github.com/securitybunker/databunker/src/utils"
)
// 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) == "" {
if e.EnforceAuth(w, r, nil) == "" {
return
}
var offset int32
@@ -19,17 +20,17 @@ func (e mainEnv) getUserRequests(w http.ResponseWriter, r *http.Request, ps http
status := "open"
args := r.URL.Query()
if value, ok := args["offset"]; ok {
offset = atoi(value[0])
offset = utils.Atoi(value[0])
}
if value, ok := args["limit"]; ok {
limit = atoi(value[0])
limit = utils.Atoi(value[0])
}
if value, ok := args["status"]; ok {
status = value[0]
}
resultJSON, counter, err := e.db.getRequests(status, offset, limit)
if err != nil {
returnError(w, r, "internal error", 405, err, nil)
ReturnError(w, r, "internal error", 405, err, nil)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
@@ -45,7 +46,7 @@ func (e mainEnv) getCustomUserRequests(w http.ResponseWriter, r *http.Request, p
event := audit("get user privacy requests", identity, mode, identity)
defer func() { event.submit(e.db, e.conf) }()
if e.enforceAuth(w, r, event) == "" {
if e.EnforceAuth(w, r, event) == "" {
return
}
userTOKEN := e.loadUserToken(w, r, mode, identity, event)
@@ -56,14 +57,14 @@ func (e mainEnv) getCustomUserRequests(w http.ResponseWriter, r *http.Request, p
var limit int32 = 10
args := r.URL.Query()
if value, ok := args["offset"]; ok {
offset = atoi(value[0])
offset = utils.Atoi(value[0])
}
if value, ok := args["limit"]; ok {
limit = atoi(value[0])
limit = utils.Atoi(value[0])
}
resultJSON, counter, err := e.db.getUserRequests(userTOKEN, offset, limit)
if err != nil {
returnError(w, r, "internal error", 405, err, nil)
ReturnError(w, r, "internal error", 405, err, nil)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
@@ -77,30 +78,30 @@ func (e mainEnv) getUserRequest(w http.ResponseWriter, r *http.Request, ps httpr
event := audit("get user request by request token", request, "request", request)
defer func() { event.submit(e.db, e.conf) }()
if enforceUUID(w, request, event) == false {
if EnforceUUID(w, request, event) == false {
return
}
requestInfo, err := e.db.getRequest(request)
if err != nil {
returnError(w, r, "internal error", 405, err, nil)
ReturnError(w, r, "internal error", 405, err, nil)
return
}
if len(requestInfo) == 0 {
returnError(w, r, "not found", 405, err, event)
ReturnError(w, r, "not found", 405, err, event)
return
}
var resultJSON []byte
action := getStringValue(requestInfo["action"])
userTOKEN := getStringValue(requestInfo["token"])
action := utils.GetStringValue(requestInfo["action"])
userTOKEN := utils.GetStringValue(requestInfo["token"])
if len(userTOKEN) != 0 {
event.Record = userTOKEN
}
if e.enforceAdmin(w, r, event) == "" {
if e.EnforceAdmin(w, r, event) == "" {
return
}
change := getStringValue(requestInfo["change"])
appName := getStringValue(requestInfo["app"])
brief := getStringValue(requestInfo["brief"])
change := utils.GetStringValue(requestInfo["change"])
appName := utils.GetStringValue(requestInfo["app"])
brief := utils.GetStringValue(requestInfo["brief"])
if strings.HasPrefix(action, "plugin") {
brief = ""
}
@@ -112,11 +113,11 @@ func (e mainEnv) getUserRequest(w http.ResponseWriter, r *http.Request, ps httpr
resultJSON, err = e.db.getUserJSON(userTOKEN)
}
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
if resultJSON == nil {
returnError(w, r, "not found", 405, err, event)
ReturnError(w, r, "not found", 405, err, event)
return
}
//fmt.Printf("Full json: %s\n", resultJSON)
@@ -145,49 +146,49 @@ func (e mainEnv) approveUserRequest(w http.ResponseWriter, r *http.Request, ps h
event := audit("approve user request", request, "request", request)
defer func() { event.submit(e.db, e.conf) }()
if enforceUUID(w, request, event) == false {
if EnforceUUID(w, request, event) == false {
return
}
authResult := e.enforceAdmin(w, r, event)
authResult := e.EnforceAdmin(w, r, event)
if authResult == "" {
return
}
records, err := getJSONPostMap(r)
records, err := utils.GetJSONPostMap(r)
if err != nil {
returnError(w, r, "failed to decode request body", 405, err, event)
ReturnError(w, r, "failed to decode request body", 405, err, event)
return
}
reason := getStringValue(records["reason"])
reason := utils.GetStringValue(records["reason"])
requestInfo, err := e.db.getRequest(request)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
if len(requestInfo) == 0 {
returnError(w, r, "not found", 405, err, event)
ReturnError(w, r, "not found", 405, err, event)
return
}
userTOKEN := getStringValue(requestInfo["token"])
userTOKEN := utils.GetStringValue(requestInfo["token"])
if len(userTOKEN) != 0 {
event.Record = userTOKEN
}
action := getStringValue(requestInfo["action"])
status := getStringValue(requestInfo["status"])
action := utils.GetStringValue(requestInfo["action"])
status := utils.GetStringValue(requestInfo["status"])
if status != "open" {
returnError(w, r, "wrong status: "+status, 405, err, event)
ReturnError(w, r, "wrong status: "+status, 405, err, event)
return
}
userJSON, userBSON, err := e.db.getUser(userTOKEN)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
if userJSON == nil {
returnError(w, r, "not found", 405, err, event)
ReturnError(w, r, "not found", 405, err, event)
return
}
if action == "forget-me" {
email := getStringValue(userBSON["email"])
email := utils.GetStringValue(userBSON["email"])
if len(email) > 0 {
e.globalUserDelete(email)
}
@@ -198,7 +199,7 @@ func (e mainEnv) approveUserRequest(w http.ResponseWriter, r *http.Request, ps h
event.Msg = "failed to delete"
}
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
notifyURL := e.conf.Notification.NotificationURL
@@ -206,21 +207,21 @@ func (e mainEnv) approveUserRequest(w http.ResponseWriter, r *http.Request, ps h
} else if action == "change-profile" {
oldJSON, newJSON, lookupErr, err := e.db.updateUserRecord(requestInfo["change"].([]uint8), userTOKEN, userBSON, event, e.conf)
if lookupErr {
returnError(w, r, "internal error", 405, errors.New("not found"), event)
ReturnError(w, r, "internal error", 405, errors.New("not found"), event)
return
}
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
returnUUID(w, userTOKEN)
utils.ReturnUUID(w, userTOKEN)
notifyURL := e.conf.Notification.NotificationURL
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)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
} else if action == "agreement-withdraw" {
@@ -243,43 +244,43 @@ func (e mainEnv) cancelUserRequest(w http.ResponseWriter, r *http.Request, ps ht
event := audit("cancel user request", request, "request", request)
defer func() { event.submit(e.db, e.conf) }()
if enforceUUID(w, request, event) == false {
if EnforceUUID(w, request, event) == false {
return
}
records, err := getJSONPostMap(r)
records, err := utils.GetJSONPostMap(r)
if err != nil {
returnError(w, r, "failed to decode request body", 405, err, event)
ReturnError(w, r, "failed to decode request body", 405, err, event)
return
}
reason := getStringValue(records["reason"])
reason := utils.GetStringValue(records["reason"])
requestInfo, err := e.db.getRequest(request)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
if len(requestInfo) == 0 {
returnError(w, r, "not found", 405, err, event)
ReturnError(w, r, "not found", 405, err, event)
return
}
userTOKEN := getStringValue(requestInfo["token"])
userTOKEN := utils.GetStringValue(requestInfo["token"])
if len(userTOKEN) != 0 {
event.Record = userTOKEN
}
authResult := e.enforceAuth(w, r, event)
authResult := e.EnforceAuth(w, r, event)
if authResult == "" {
return
}
if requestInfo["status"].(string) != "open" {
returnError(w, r, "wrong status: "+requestInfo["status"].(string), 405, err, event)
ReturnError(w, r, "wrong status: "+requestInfo["status"].(string), 405, err, event)
return
}
resultJSON, err := e.db.getUserJSON(userTOKEN)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
if resultJSON == nil {
returnError(w, r, "not found", 405, err, event)
ReturnError(w, r, "not found", 405, err, event)
return
}
if len(reason) == 0 && authResult == "login" {

View File

@@ -15,6 +15,7 @@ import (
"time"
"github.com/securitybunker/databunker/src/storage"
"github.com/securitybunker/databunker/src/utils"
)
func loadService() {
@@ -34,14 +35,14 @@ func loadService() {
}
log.Printf("Databunker version: %s\n", version)
var cfg Config
readEnv(&cfg)
readConfFile(&cfg, confPtr)
ReadEnv(&cfg)
ReadConfFile(&cfg, confPtr)
customRootToken := ""
if *demoPtr {
customRootToken = "DEMO"
} else {
customRootToken = getArgEnvFileVariable("DATABUNKER_ROOTTOKEN", rootTokenKeyPtr)
customRootToken = utils.GetArgEnvFileVariable("DATABUNKER_ROOTTOKEN", rootTokenKeyPtr)
}
if *initPtr || *demoPtr {
if storage.DBExists(dbPtr) == true {
@@ -63,7 +64,7 @@ func loadService() {
log.Println(`Run "databunker -init" for the first time to generate keys and init database.`)
os.Exit(0)
}
masterKeyStr := getArgEnvFileVariable("DATABUNKER_MASTERKEY", masterKeyPtr)
masterKeyStr := utils.GetArgEnvFileVariable("DATABUNKER_MASTERKEY", masterKeyPtr)
if *startPtr == false {
log.Println(`'databunker -start' command is missing.`)
os.Exit(0)
@@ -149,7 +150,7 @@ func decodeMasterkey(masterKeyStr string) ([]byte, error) {
if len(masterKeyStr) != 48 {
return nil, errors.New("Master key length is wrong")
}
if isValidHex(masterKeyStr) == false {
if utils.CheckValidHex(masterKeyStr) == false {
return nil, errors.New("Master key is not valid hex string")
}
masterKey, err := hex.DecodeString(masterKeyStr)
@@ -163,7 +164,7 @@ func setupDB(dbPtr *string, masterKeyPtr *string, customRootToken string) (*dbco
log.Println("Databunker init")
var masterKey []byte
var err error
masterKeyString := getArgEnvFileVariable("DATABUNKER_MASTERKEY", masterKeyPtr)
masterKeyString := utils.GetArgEnvFileVariable("DATABUNKER_MASTERKEY", masterKeyPtr)
if len(masterKeyString) > 0 {
masterKey, err = decodeMasterkey(masterKeyString)
if err != nil {

View File

@@ -10,6 +10,7 @@ import (
uuid "github.com/hashicorp/go-uuid"
"github.com/julienschmidt/httprouter"
"github.com/securitybunker/databunker/src/storage"
"github.com/securitybunker/databunker/src/utils"
"go.mongodb.org/mongo-driver/bson"
)
@@ -21,30 +22,30 @@ func (e mainEnv) createSession(w http.ResponseWriter, r *http.Request, ps httpro
event.submit(e.db, e.conf)
}
}()
if enforceUUID(w, session, event) == false {
//returnError(w, r, "bad session format", nil, event)
if EnforceUUID(w, session, event) == false {
//ReturnError(w, r, "bad session format", nil, event)
return
}
if e.enforceAdmin(w, r, event) == "" {
if e.EnforceAdmin(w, r, event) == "" {
return
}
records, err := getJSONPostMap(r)
records, err := utils.GetJSONPostMap(r)
if err != nil {
returnError(w, r, "failed to decode request body", 405, err, event)
ReturnError(w, r, "failed to decode request body", 405, err, event)
return
}
if len(records) == 0 {
returnError(w, r, "empty body", 405, nil, event)
ReturnError(w, r, "empty body", 405, nil, event)
return
}
expirationStr := getStringValue(records["expiration"])
expiration := setExpiration(e.conf.Policy.MaxSessionRetentionPeriod, expirationStr)
expirationStr := utils.GetStringValue(records["expiration"])
expiration := utils.SetExpiration(e.conf.Policy.MaxSessionRetentionPeriod, expirationStr)
log.Printf("Record expiration: %s", expiration)
userToken := getStringValue(records["token"])
userLogin := getStringValue(records["login"])
userEmail := getStringValue(records["email"])
userPhone := getStringValue(records["phone"])
userCustomIdx := getStringValue(records["custom"])
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"])
var userBson bson.M
if len(userLogin) > 0 {
@@ -59,7 +60,7 @@ func (e mainEnv) createSession(w http.ResponseWriter, r *http.Request, ps httpro
userBson, err = e.db.lookupUserRecord(userToken)
}
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
userTOKEN := ""
@@ -70,12 +71,12 @@ func (e mainEnv) createSession(w http.ResponseWriter, r *http.Request, ps httpro
}
jsonData, err := json.Marshal(records)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
session, err = e.db.createSessionRecord(session, userTOKEN, expiration, jsonData)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
@@ -87,11 +88,11 @@ func (e mainEnv) deleteSession(w http.ResponseWriter, r *http.Request, ps httpro
session := ps.ByName("session")
event := audit("delete session", session, "session", session)
defer func() { event.submit(e.db, e.conf) }()
if enforceUUID(w, session, event) == false {
//returnError(w, r, "bad session format", nil, event)
if EnforceUUID(w, session, event) == false {
//ReturnError(w, r, "bad session format", nil, event)
return
}
if e.enforceAdmin(w, r, event) == "" {
if e.EnforceAdmin(w, r, event) == "" {
return
}
e.db.deleteSession(session)
@@ -111,34 +112,34 @@ func (e mainEnv) newUserSession(w http.ResponseWriter, r *http.Request, ps httpr
if userTOKEN == "" {
return
}
if e.enforceAuth(w, r, event) == "" {
if e.EnforceAuth(w, r, event) == "" {
return
}
records, err := getJSONPostMap(r)
records, err := utils.GetJSONPostMap(r)
if err != nil {
returnError(w, r, "failed to decode request body", 405, err, event)
ReturnError(w, r, "failed to decode request body", 405, err, event)
return
}
if len(records) == 0 {
returnError(w, r, "empty body", 405, nil, event)
ReturnError(w, r, "empty body", 405, nil, event)
return
}
expirationStr := getStringValue(records["expiration"])
expiration := setExpiration(e.conf.Policy.MaxSessionRetentionPeriod, expirationStr)
expirationStr := utils.GetStringValue(records["expiration"])
expiration := utils.SetExpiration(e.conf.Policy.MaxSessionRetentionPeriod, expirationStr)
log.Printf("Record expiration: %s", expiration)
jsonData, err := json.Marshal(records)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
sessionUUID, err := uuid.GenerateUUID()
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
sessionID, err := e.db.createSessionRecord(sessionUUID, userTOKEN, expiration, jsonData)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
@@ -156,7 +157,7 @@ func (e mainEnv) getUserSessions(w http.ResponseWriter, r *http.Request, ps http
if userTOKEN == "" {
return
}
if e.enforceAuth(w, r, event) == "" {
if e.EnforceAuth(w, r, event) == "" {
return
}
e.db.store.DeleteExpired(storage.TblName.Sessions, "token", userTOKEN)
@@ -164,14 +165,14 @@ func (e mainEnv) getUserSessions(w http.ResponseWriter, r *http.Request, ps http
var offset int32
var limit int32 = 10
if value, ok := args["offset"]; ok {
offset = atoi(value[0])
offset = utils.Atoi(value[0])
}
if value, ok := args["limit"]; ok {
limit = atoi(value[0])
limit = utils.Atoi(value[0])
}
records, count, err := e.db.getUserSessionsByToken(userTOKEN, offset, limit)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
data := strings.Join(records, ",")
@@ -194,11 +195,11 @@ func (e mainEnv) getSession(w http.ResponseWriter, r *http.Request, ps httproute
e.db.store.DeleteExpired(storage.TblName.Sessions, "token", userTOKEN)
}
if err != nil {
returnError(w, r, err.Error(), 405, err, event)
ReturnError(w, r, err.Error(), 405, err, event)
return
}
if e.enforceAuth(w, r, event) == "" {
if e.EnforceAuth(w, r, event) == "" {
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")

View File

@@ -7,6 +7,7 @@ import (
"time"
"github.com/securitybunker/databunker/src/storage"
"github.com/securitybunker/databunker/src/utils"
"go.mongodb.org/mongo-driver/bson"
)
@@ -20,7 +21,7 @@ func (dbobj dbcon) createSessionRecord(sessionUUID string, userTOKEN string, exp
var err error
now := int32(time.Now().Unix())
if len(expiration) > 0 {
endtime, err = parseExpiration(expiration)
endtime, err = utils.ParseExpiration(expiration)
if err != nil {
return "", err
}

View File

@@ -9,6 +9,7 @@ import (
"strings"
"github.com/julienschmidt/httprouter"
"github.com/securitybunker/databunker/src/utils"
"github.com/tidwall/gjson"
)
@@ -22,12 +23,12 @@ func (e mainEnv) newSharedRecord(w http.ResponseWriter, r *http.Request, ps http
if userTOKEN == "" {
return
}
if e.enforceAuth(w, r, event) == "" {
if e.EnforceAuth(w, r, event) == "" {
return
}
records, err := getJSONPostMap(r)
records, err := utils.GetJSONPostMap(r)
if err != nil {
returnError(w, r, "failed to decode request body", 405, err, event)
ReturnError(w, r, "failed to decode request body", 405, err, event)
return
}
fields := ""
@@ -52,21 +53,21 @@ func (e mainEnv) newSharedRecord(w http.ResponseWriter, r *http.Request, ps http
}
if value, ok := records["expiration"]; ok {
if reflect.TypeOf(value) == reflect.TypeOf("string") {
expiration = setExpiration(e.conf.Policy.MaxShareableRecordRetentionPeriod, value.(string))
expiration = utils.SetExpiration(e.conf.Policy.MaxShareableRecordRetentionPeriod, value.(string))
} else {
returnError(w, r, "failed to parse expiration field", 405, err, event)
ReturnError(w, r, "failed to parse expiration field", 405, err, event)
return
}
}
if value, ok := records["app"]; ok {
if reflect.TypeOf(value) == reflect.TypeOf("string") {
appName = strings.ToLower(value.(string))
if len(appName) > 0 && isValidApp(appName) == false {
returnError(w, r, "unknown app name", 405, nil, event)
if len(appName) > 0 && utils.CheckValidApp(appName) == false {
ReturnError(w, r, "unknown app name", 405, nil, event)
}
} else {
// type is different
returnError(w, r, "failed to parse app field", 405, nil, event)
ReturnError(w, r, "failed to parse app field", 405, nil, event)
}
}
if len(expiration) == 0 {
@@ -75,7 +76,7 @@ func (e mainEnv) newSharedRecord(w http.ResponseWriter, r *http.Request, ps http
}
recordUUID, err := e.db.saveSharedRecord(userTOKEN, fields, expiration, session, appName, partner, e.conf)
if err != nil {
returnError(w, r, err.Error(), 405, err, event)
ReturnError(w, r, err.Error(), 405, err, event)
return
}
event.Record = userTOKEN
@@ -90,7 +91,7 @@ func (e mainEnv) getRecord(w http.ResponseWriter, r *http.Request, ps httprouter
event := audit("get shareable record by token", record, "record", record)
defer func() { event.submit(e.db, e.conf) }()
if enforceUUID(w, record, event) == false {
if EnforceUUID(w, record, event) == false {
return
}
recordInfo, err := e.db.getSharedRecord(record)
@@ -114,18 +115,18 @@ func (e mainEnv) getRecord(w http.ResponseWriter, r *http.Request, ps httprouter
resultJSON, err = e.db.getUserJSON(recordInfo.token)
}
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
if resultJSON == nil {
returnError(w, r, "not found", 405, err, event)
ReturnError(w, r, "not found", 405, err, event)
return
}
log.Printf("Full json: %s\n", resultJSON)
if len(recordInfo.fields) > 0 {
raw := make(map[string]interface{})
//var newJSON json
allFields := parseFields(recordInfo.fields)
allFields := utils.ParseFields(recordInfo.fields)
for _, f := range allFields {
if f == "token" {
raw["token"] = recordInfo.token

View File

@@ -8,11 +8,12 @@ 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"
)
func (dbobj dbcon) saveSharedRecord(userTOKEN string, fields string, expiration string, session string, appName string, partner string, conf Config) (string, error) {
if isValidUUID(userTOKEN) == false {
if utils.CheckValidUUID(userTOKEN) == false {
return "", errors.New("bad uuid")
}
if len(expiration) == 0 {
@@ -26,7 +27,7 @@ func (dbobj dbcon) saveSharedRecord(userTOKEN string, fields string, expiration
}
log.Printf("Expiration is : %s\n", expiration)
start, err := parseExpiration(expiration)
start, err := utils.ParseExpiration(expiration)
if err != nil {
return "", err
}
@@ -67,7 +68,7 @@ func (dbobj dbcon) saveSharedRecord(userTOKEN string, fields string, expiration
func (dbobj dbcon) getSharedRecord(recordUUID string) (checkRecordResult, error) {
var result checkRecordResult
//if isValidUUID(recordUUID) == false {
//if utils.CheckValidUUID(recordUUID) == false {
// return result, errors.New("failed to authenticate")
//}
record, err := dbobj.store.GetRecord(storage.TblName.Sharedrecords, "record", recordUUID)

View File

@@ -861,7 +861,7 @@ func (dbobj MySQLDB) GetAllTables() ([]string, error) {
// ValidateNewApp function check if app name can be part of the table name
func (dbobj MySQLDB) ValidateNewApp(appName string) bool {
if contains(allTables, appName) == true {
if SliceContains(allTables, appName) == true {
return true
}
return true
@@ -891,7 +891,7 @@ func (dbobj MySQLDB) execQueries(queries []string) error {
// CreateNewAppTable creates a new app table and creates indexes for it.
func (dbobj MySQLDB) CreateNewAppTable(appName string) {
if contains(allTables, appName) == false {
if SliceContains(allTables, appName) == false {
// it is a new app, create an index
log.Printf("This is a new app, creating table & index for: %s\n", appName)
queries := []string{

View File

@@ -865,7 +865,7 @@ func (dbobj PGSQLDB) GetAllTables() ([]string, error) {
// ValidateNewApp function check if app name can be part of the table name
func (dbobj PGSQLDB) ValidateNewApp(appName string) bool {
if contains(allTables, appName) == true {
if SliceContains(allTables, appName) == true {
return true
}
if len(allTables) >= 100 {
@@ -898,7 +898,7 @@ func (dbobj PGSQLDB) execQueries(queries []string) error {
// CreateNewAppTable creates a new app table and creates indexes for it.
func (dbobj PGSQLDB) CreateNewAppTable(appName string) {
if contains(allTables, appName) == false {
if SliceContains(allTables, appName) == false {
// it is a new app, create an index
log.Printf("This is a new app, creating table & index for: %s\n", appName)
queries := []string{

View File

@@ -849,7 +849,7 @@ func (dbobj SQLiteDB) GetAllTables() ([]string, error) {
// ValidateNewApp function check if app name can be part of the table name
func (dbobj SQLiteDB) ValidateNewApp(appName string) bool {
if contains(knownApps, appName) == true {
if SliceContains(knownApps, appName) == true {
return true
}
return true
@@ -875,7 +875,7 @@ func (dbobj SQLiteDB) execQueries(queries []string) error {
// CreateNewAppTable creates a new app table and creates indexes for it.
func (dbobj SQLiteDB) CreateNewAppTable(appName string) {
if contains(knownApps, appName) == false {
if SliceContains(knownApps, appName) == false {
// it is a new app, create an index
log.Printf("This is a new app, creating table & index for: %s\n", appName)
queries := []string{"CREATE TABLE IF NOT EXISTS " + appName + ` (

View File

@@ -143,7 +143,7 @@ func CreateTestDB() string {
return db.CreateTestDB()
}
func contains(slice []string, item string) bool {
func SliceContains(slice []string, item string) bool {
set := make(map[string]struct{}, len(slice))
for _, s := range slice {
set[s] = struct{}{}

View File

@@ -7,6 +7,7 @@ import (
"strings"
"github.com/julienschmidt/httprouter"
"github.com/securitybunker/databunker/src/utils"
)
func (e mainEnv) userappNew(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
@@ -20,38 +21,38 @@ func (e mainEnv) userappNew(w http.ResponseWriter, r *http.Request, ps httproute
if userTOKEN == "" {
return
}
if e.enforceAuth(w, r, event) == "" {
if e.EnforceAuth(w, r, event) == "" {
return
}
if isValidApp(appName) == false {
returnError(w, r, "bad appname", 405, nil, event)
if utils.CheckValidApp(appName) == false {
ReturnError(w, r, "bad appname", 405, nil, event)
return
}
if e.db.store.ValidateNewApp("app_"+appName) == false {
returnError(w, r, "db limitation", 405, nil, event)
ReturnError(w, r, "db limitation", 405, nil, event)
return
}
data, err := getJSONPostMap(r)
data, err := utils.GetJSONPostMap(r)
if err != nil {
returnError(w, r, "failed to decode request body", 405, err, event)
ReturnError(w, r, "failed to decode request body", 405, err, event)
return
}
if len(data) == 0 {
returnError(w, r, "empty body", 405, nil, event)
ReturnError(w, r, "empty body", 405, nil, event)
return
}
jsonData, err := json.Marshal(data)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
_, err = e.db.createAppRecord(jsonData, userTOKEN, appName, event, e.conf)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
returnUUID(w, userTOKEN)
utils.ReturnUUID(w, userTOKEN)
return
}
@@ -65,58 +66,58 @@ func (e mainEnv) userappChange(w http.ResponseWriter, r *http.Request, ps httpro
if userTOKEN == "" {
return
}
authResult := e.enforceAuth(w, r, event)
authResult := e.EnforceAuth(w, r, event)
if authResult == "" {
return
}
if isValidApp(appName) == false {
returnError(w, r, "bad appname", 405, nil, event)
if utils.CheckValidApp(appName) == false {
ReturnError(w, r, "bad appname", 405, nil, event)
return
}
jsonData, err := getJSONPostData(r)
jsonData, err := utils.GetJSONPostData(r)
if err != nil {
returnError(w, r, "failed to decode request body", 405, err, event)
ReturnError(w, r, "failed to decode request body", 405, err, event)
return
}
if jsonData == nil {
returnError(w, r, "empty body", 405, nil, event)
ReturnError(w, r, "empty body", 405, nil, event)
return
}
// make sure userapp exists
resultJSON, err := e.db.getUserApp(userTOKEN, appName, e.conf)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
if resultJSON == nil {
returnError(w, r, "not found", 405, nil, event)
ReturnError(w, r, "not found", 405, nil, event)
return
}
if authResult != "login" {
_, err = e.db.updateAppRecord(jsonData, userTOKEN, appName, event, e.conf)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
returnUUID(w, userTOKEN)
utils.ReturnUUID(w, userTOKEN)
return
}
if e.conf.SelfService.AppRecordChange != nil {
for _, name := range e.conf.SelfService.AppRecordChange {
if stringPatternMatch(strings.ToLower(name), appName) {
if utils.StringPatternMatch(strings.ToLower(name), appName) {
_, err = e.db.updateAppRecord(jsonData, userTOKEN, appName, event, e.conf)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
returnUUID(w, userTOKEN)
utils.ReturnUUID(w, userTOKEN)
return
}
}
}
rtoken, rstatus, err := e.db.saveUserRequest("change-app-data", userTOKEN, appName, "", jsonData, e.conf)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
@@ -133,12 +134,12 @@ func (e mainEnv) userappList(w http.ResponseWriter, r *http.Request, ps httprout
if userTOKEN == "" {
return
}
if e.enforceAuth(w, r, event) == "" {
if e.EnforceAuth(w, r, event) == "" {
return
}
result, err := e.db.listUserApps(userTOKEN, e.conf)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
@@ -156,20 +157,20 @@ func (e mainEnv) userappGet(w http.ResponseWriter, r *http.Request, ps httproute
if userTOKEN == "" {
return
}
if e.enforceAuth(w, r, event) == "" {
if e.EnforceAuth(w, r, event) == "" {
return
}
if isValidApp(appName) == false {
returnError(w, r, "bad appname", 405, nil, event)
if utils.CheckValidApp(appName) == false {
ReturnError(w, r, "bad appname", 405, nil, event)
return
}
resultJSON, err := e.db.getUserApp(userTOKEN, appName, e.conf)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
if resultJSON == nil {
returnError(w, r, "not found", 405, nil, event)
ReturnError(w, r, "not found", 405, nil, event)
return
}
finalJSON := fmt.Sprintf(`{"status":"ok","token":"%s","data":%s}`, userTOKEN, resultJSON)
@@ -188,11 +189,11 @@ func (e mainEnv) userappDelete(w http.ResponseWriter, r *http.Request, ps httpro
if userTOKEN == "" {
return
}
if e.enforceAuth(w, r, event) == "" {
if e.EnforceAuth(w, r, event) == "" {
return
}
if isValidApp(appName) == false {
returnError(w, r, "bad appname", 405, nil, event)
if utils.CheckValidApp(appName) == false {
ReturnError(w, r, "bad appname", 405, nil, event)
return
}
@@ -205,12 +206,12 @@ func (e mainEnv) userappDelete(w http.ResponseWriter, r *http.Request, ps httpro
}
func (e mainEnv) appList(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
if e.enforceAuth(w, r, nil) == "" {
if e.EnforceAuth(w, r, nil) == "" {
return
}
result, err := e.db.listAllApps(e.conf)
if err != nil {
returnError(w, r, "internal error", 405, err, nil)
ReturnError(w, r, "internal error", 405, err, nil)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")

View File

@@ -8,6 +8,7 @@ import (
"github.com/julienschmidt/httprouter"
"github.com/securitybunker/databunker/src/storage"
"github.com/securitybunker/databunker/src/utils"
"go.mongodb.org/mongo-driver/bson"
)
@@ -17,98 +18,98 @@ 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.EnforceAuth(w, r, event) == "" {
log.Println("Failed to create user, access denied, try to configure Create_user_without_access_token")
return
}
}
userJSON, err := getUserJSON(r, e.conf.Sms.DefaultCountry)
userJSON, err := utils.GetUserJSONStruct(r, e.conf.Sms.DefaultCountry)
if err != nil {
returnError(w, r, "failed to decode request body", 405, err, event)
ReturnError(w, r, "failed to decode request body", 405, err, event)
return
}
if len(userJSON.jsonData) == 0 {
returnError(w, r, "empty request body", 405, nil, event)
if len(userJSON.JsonData) == 0 {
ReturnError(w, r, "empty request body", 405, nil, event)
return
}
err = validateUserRecord(userJSON.jsonData)
err = validateUserRecord(userJSON.JsonData)
if err != nil {
returnError(w, r, "user schema error: "+err.Error(), 405, err, event)
ReturnError(w, r, "user schema error: "+err.Error(), 405, err, event)
return
}
// make sure that login, email and phone are unique
if len(userJSON.loginIdx) > 0 {
otherUserBson, err := e.db.lookupUserRecordByIndex("login", userJSON.loginIdx, e.conf)
if len(userJSON.LoginIdx) > 0 {
otherUserBson, err := e.db.lookupUserRecordByIndex("login", userJSON.LoginIdx, e.conf)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
if otherUserBson != nil {
returnError(w, r, "duplicate index: login", 405, nil, event)
ReturnError(w, r, "duplicate index: login", 405, nil, event)
return
}
}
if len(userJSON.emailIdx) > 0 {
otherUserBson, err := e.db.lookupUserRecordByIndex("email", userJSON.emailIdx, e.conf)
if len(userJSON.EmailIdx) > 0 {
otherUserBson, err := e.db.lookupUserRecordByIndex("email", userJSON.EmailIdx, e.conf)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
if otherUserBson != nil {
returnError(w, r, "duplicate index: email", 405, nil, event)
ReturnError(w, r, "duplicate index: email", 405, nil, event)
return
}
}
if len(userJSON.phoneIdx) > 0 {
otherUserBson, err := e.db.lookupUserRecordByIndex("phone", userJSON.phoneIdx, e.conf)
if len(userJSON.PhoneIdx) > 0 {
otherUserBson, err := e.db.lookupUserRecordByIndex("phone", userJSON.PhoneIdx, e.conf)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
if otherUserBson != nil {
returnError(w, r, "duplicate index: phone", 405, nil, event)
ReturnError(w, r, "duplicate index: phone", 405, nil, event)
return
}
}
if len(userJSON.customIdx) > 0 {
otherUserBson, err := e.db.lookupUserRecordByIndex("custom", userJSON.customIdx, e.conf)
if len(userJSON.CustomIdx) > 0 {
otherUserBson, err := e.db.lookupUserRecordByIndex("custom", userJSON.CustomIdx, e.conf)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
if otherUserBson != nil {
returnError(w, r, "duplicate index: custom", 405, nil, event)
ReturnError(w, r, "duplicate index: custom", 405, nil, event)
return
}
}
if len(userJSON.loginIdx) == 0 &&
len(userJSON.emailIdx) == 0 &&
len(userJSON.phoneIdx) == 0 &&
len(userJSON.customIdx) == 0 {
returnError(w, r, "failed to create user, all user lookup fields are missing", 405, err, event)
if len(userJSON.LoginIdx) == 0 &&
len(userJSON.EmailIdx) == 0 &&
len(userJSON.PhoneIdx) == 0 &&
len(userJSON.CustomIdx) == 0 {
ReturnError(w, r, "failed to create user, all user lookup fields are missing", 405, err, event)
return
}
userTOKEN, err := e.db.createUserRecord(userJSON, event)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
encPhoneIdx := ""
if len(userJSON.emailIdx) > 0 {
encEmailIdx, _ := basicStringEncrypt(userJSON.emailIdx, e.db.masterKey, e.db.GetCode())
if len(userJSON.EmailIdx) > 0 {
encEmailIdx, _ := basicStringEncrypt(userJSON.EmailIdx, e.db.masterKey, e.db.GetCode())
e.db.linkAgreementRecords(userTOKEN, encEmailIdx)
}
if len(userJSON.phoneIdx) > 0 {
encPhoneIdx, _ = basicStringEncrypt(userJSON.phoneIdx, e.db.masterKey, e.db.GetCode())
if len(userJSON.PhoneIdx) > 0 {
encPhoneIdx, _ = basicStringEncrypt(userJSON.PhoneIdx, e.db.masterKey, e.db.GetCode())
e.db.linkAgreementRecords(userTOKEN, encPhoneIdx)
}
if len(userJSON.emailIdx) > 0 && len(userJSON.phoneIdx) > 0 {
if len(userJSON.EmailIdx) > 0 && len(userJSON.PhoneIdx) > 0 {
// delete duplicate consent records for user
records, _ := e.db.store.GetList(storage.TblName.Agreements, "token", userTOKEN, 0, 0, "")
var briefCodes []string
for _, val := range records {
if contains(briefCodes, val["brief"].(string)) == true {
if utils.SliceContains(briefCodes, val["brief"].(string)) == true {
e.db.store.DeleteRecord2(storage.TblName.Agreements, "token", userTOKEN, "who", encPhoneIdx)
} else {
briefCodes = append(briefCodes, val["brief"].(string))
@@ -116,9 +117,9 @@ func (e mainEnv) userCreate(w http.ResponseWriter, r *http.Request, ps httproute
}
}
event.Record = userTOKEN
returnUUID(w, userTOKEN)
utils.ReturnUUID(w, userTOKEN)
notifyURL := e.conf.Notification.NotificationURL
notifyProfileNew(notifyURL, userJSON.jsonData, "token", userTOKEN)
notifyProfileNew(notifyURL, userJSON.JsonData, "token", userTOKEN)
}
func (e mainEnv) userGet(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
@@ -129,14 +130,14 @@ func (e mainEnv) userGet(w http.ResponseWriter, r *http.Request, ps httprouter.P
event := audit("get user record by "+mode, identity, mode, identity)
defer func() { event.submit(e.db, e.conf) }()
if validateMode(mode) == false {
returnError(w, r, "bad mode", 405, nil, event)
if utils.ValidateMode(mode) == false {
ReturnError(w, r, "bad mode", 405, nil, event)
return
}
userTOKEN := ""
authResult := ""
if mode == "token" {
if enforceUUID(w, identity, event) == false {
if EnforceUUID(w, identity, event) == false {
return
}
resultJSON, err = e.db.getUserJSON(identity)
@@ -146,15 +147,15 @@ func (e mainEnv) userGet(w http.ResponseWriter, r *http.Request, ps httprouter.P
event.Record = userTOKEN
}
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
authResult = e.enforceAuth(w, r, event)
authResult = e.EnforceAuth(w, r, event)
if authResult == "" {
return
}
if resultJSON == nil {
returnError(w, r, "record not found", 405, nil, event)
ReturnError(w, r, "record not found", 405, nil, event)
return
}
finalJSON := fmt.Sprintf(`{"status":"ok","token":"%s","data":%s}`, userTOKEN, resultJSON)
@@ -166,21 +167,21 @@ func (e mainEnv) userGet(w http.ResponseWriter, r *http.Request, ps httprouter.P
}
func (e mainEnv) userList(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
if e.enforceAdmin(w, r, nil) == "" {
if e.EnforceAdmin(w, r, nil) == "" {
return
}
if e.conf.Generic.ListUsers == false {
returnError(w, r, "access denied", 403, nil, nil)
ReturnError(w, r, "access denied", 403, nil, nil)
return
}
var offset int32 = 0
var limit int32 = 10
args := r.URL.Query()
if value, ok := args["offset"]; ok {
offset = atoi(value[0])
offset = utils.Atoi(value[0])
}
if value, ok := args["limit"]; ok {
limit = atoi(value[0])
limit = utils.Atoi(value[0])
}
resultJSON, counter, _ := e.db.getUsers(offset, limit)
log.Printf("Total count of events: %d\n", counter)
@@ -201,25 +202,25 @@ func (e mainEnv) userChange(w http.ResponseWriter, r *http.Request, ps httproute
event := audit("change user record by "+mode, identity, mode, identity)
defer func() { event.submit(e.db, e.conf) }()
if validateMode(mode) == false {
returnError(w, r, "bad index", 405, nil, event)
if utils.ValidateMode(mode) == false {
ReturnError(w, r, "bad index", 405, nil, event)
return
}
jsonData, err := getJSONPostData(r)
jsonData, err := utils.GetJSONPostData(r)
if err != nil {
returnError(w, r, "failed to decode request body", 405, err, event)
ReturnError(w, r, "failed to decode request body", 405, err, event)
return
}
if jsonData == nil {
returnError(w, r, "empty request body", 405, nil, event)
ReturnError(w, r, "empty request body", 405, nil, event)
return
}
userTOKEN := ""
var userJSON []byte
var userBSON bson.M
if mode == "token" {
if enforceUUID(w, identity, event) == false {
if EnforceUUID(w, identity, event) == false {
return
}
userTOKEN = identity
@@ -229,14 +230,14 @@ func (e mainEnv) userChange(w http.ResponseWriter, r *http.Request, ps httproute
event.Record = userTOKEN
}
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
if userJSON == nil {
returnError(w, r, "user record not found", 405, nil, event)
ReturnError(w, r, "user record not found", 405, nil, event)
return
}
authResult := e.enforceAuth(w, r, event)
authResult := e.EnforceAuth(w, r, event)
if authResult == "" {
return
}
@@ -244,7 +245,7 @@ func (e mainEnv) userChange(w http.ResponseWriter, r *http.Request, ps httproute
if UserSchemaEnabled() {
adminRecordChanged, err = e.db.validateUserRecordChange(userJSON, jsonData, userTOKEN, authResult)
if err != nil {
returnError(w, r, "schema validation error: "+err.Error(), 405, err, event)
ReturnError(w, r, "schema validation error: "+err.Error(), 405, err, event)
return
}
}
@@ -253,7 +254,7 @@ func (e mainEnv) userChange(w http.ResponseWriter, r *http.Request, ps httproute
if e.conf.SelfService.UserRecordChange == false || adminRecordChanged == true {
rtoken, rstatus, err := e.db.saveUserRequest("change-profile", userTOKEN, "", "", jsonData, e.conf)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
@@ -264,14 +265,14 @@ func (e mainEnv) userChange(w http.ResponseWriter, r *http.Request, ps httproute
}
oldJSON, newJSON, lookupErr, err := e.db.updateUserRecord(jsonData, userTOKEN, userBSON, event, e.conf)
if lookupErr {
returnError(w, r, "record not found", 405, errors.New("record not found"), event)
ReturnError(w, r, "record not found", 405, errors.New("record not found"), event)
return
}
if err != nil {
returnError(w, r, "error updating user", 405, err, event)
ReturnError(w, r, "error updating user", 405, err, event)
return
}
returnUUID(w, userTOKEN)
utils.ReturnUUID(w, userTOKEN)
notifyURL := e.conf.Notification.NotificationURL
notifyProfileChange(notifyURL, oldJSON, newJSON, "token", userTOKEN)
}
@@ -283,8 +284,8 @@ func (e mainEnv) userDelete(w http.ResponseWriter, r *http.Request, ps httproute
event := audit("delete user record by "+mode, identity, mode, identity)
defer func() { event.submit(e.db, e.conf) }()
if validateMode(mode) == false {
returnError(w, r, "bad mode", 405, nil, event)
if utils.ValidateMode(mode) == false {
ReturnError(w, r, "bad mode", 405, nil, event)
return
}
var err error
@@ -292,7 +293,7 @@ func (e mainEnv) userDelete(w http.ResponseWriter, r *http.Request, ps httproute
var userJSON []byte
userTOKEN := identity
if mode == "token" {
if enforceUUID(w, identity, event) == false {
if EnforceUUID(w, identity, event) == false {
return
}
userJSON, userBSON, err = e.db.getUser(identity)
@@ -301,10 +302,10 @@ func (e mainEnv) userDelete(w http.ResponseWriter, r *http.Request, ps httproute
event.Record = userTOKEN
}
if err != nil {
returnError(w, r, "internal error", 405, nil, event)
ReturnError(w, r, "internal error", 405, nil, event)
return
}
authResult := e.enforceAuth(w, r, event)
authResult := e.EnforceAuth(w, r, event)
if authResult == "" {
return
}
@@ -315,7 +316,7 @@ func (e mainEnv) userDelete(w http.ResponseWriter, r *http.Request, ps httproute
w.WriteHeader(200)
fmt.Fprintf(w, `{"status":"ok","result":"done"}`)
}
returnError(w, r, "record not found", 405, nil, event)
ReturnError(w, r, "record not found", 405, nil, event)
return
}
@@ -324,7 +325,7 @@ func (e mainEnv) userDelete(w http.ResponseWriter, r *http.Request, ps httproute
if e.conf.SelfService.ForgetMe == false {
rtoken, rstatus, err := e.db.saveUserRequest("forget-me", userTOKEN, "", "", nil, e.conf)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
@@ -333,14 +334,14 @@ func (e mainEnv) userDelete(w http.ResponseWriter, r *http.Request, ps httproute
return
}
}
email := getStringValue(userBSON["email"])
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)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
@@ -366,12 +367,12 @@ func (e mainEnv) userPrelogin(w http.ResponseWriter, r *http.Request, ps httprou
return
}
if mode != "phone" && mode != "email" {
returnError(w, r, "bad mode", 405, nil, event)
ReturnError(w, r, "bad mode", 405, nil, event)
return
}
userBson, err := e.db.lookupUserRecordByIndex(mode, identity, e.conf)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
if userBson != nil {
@@ -394,7 +395,7 @@ func (e mainEnv) userPrelogin(w http.ResponseWriter, r *http.Request, ps httprou
//notifyURL := e.conf.Notification.NotificationURL
//notifyBadLogin(notifyURL, mode, identity)
e.pluginUserLookup(identity)
//returnError(w, r, "record not found", 405, errors.New("record not found"), event)
//ReturnError(w, r, "record not found", 405, errors.New("record not found"), event)
captcha, _ := generateCaptcha()
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(403)
@@ -409,20 +410,20 @@ func (e mainEnv) userPrelogin(w http.ResponseWriter, r *http.Request, ps httprou
}
func (e mainEnv) userLogin(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
tmp := atoi(ps.ByName("tmp"))
tmp := utils.Atoi(ps.ByName("tmp"))
identity := ps.ByName("identity")
mode := ps.ByName("mode")
event := audit("user login by "+mode, identity, mode, identity)
defer func() { event.submit(e.db, e.conf) }()
if mode != "phone" && mode != "email" {
returnError(w, r, "bad mode", 405, nil, event)
ReturnError(w, r, "bad mode", 405, nil, event)
return
}
userBson, err := e.db.lookupUserRecordByIndex(mode, identity, e.conf)
if userBson == nil || err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
@@ -438,7 +439,7 @@ func (e mainEnv) userLogin(w http.ResponseWriter, r *http.Request, ps httprouter
xtoken, hashedToken, err := e.db.generateUserLoginXtoken(userTOKEN)
//fmt.Printf("generate user access token: %s\n", xtoken)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
ReturnError(w, r, "internal error", 405, err, event)
return
}
event.Msg = "generated: " + hashedToken
@@ -447,5 +448,5 @@ func (e mainEnv) userLogin(w http.ResponseWriter, r *http.Request, ps httprouter
fmt.Fprintf(w, `{"status":"ok","xtoken":"%s","token":"%s"}`, xtoken, userTOKEN)
return
}
returnError(w, r, "internal error", 405, nil, event)
ReturnError(w, r, "internal error", 405, nil, event)
}

View File

@@ -12,10 +12,11 @@ import (
jsonpatch "github.com/evanphx/json-patch"
uuid "github.com/hashicorp/go-uuid"
"github.com/securitybunker/databunker/src/storage"
"github.com/securitybunker/databunker/src/utils"
"go.mongodb.org/mongo-driver/bson"
)
func (dbobj dbcon) createUserRecord(parsedData userJSON, event *auditEvent) (string, error) {
func (dbobj dbcon) createUserRecord(parsedData utils.UserJSONStruct, event *auditEvent) (string, error) {
var userTOKEN string
//var bdoc interface{}
bdoc := bson.M{}
@@ -28,7 +29,7 @@ func (dbobj dbcon) createUserRecord(parsedData userJSON, event *auditEvent) (str
return "", err
}
//err = bson.UnmarshalExtJSON(jsonData, false, &bdoc)
encoded, err := encrypt(dbobj.masterKey, userKeyBinary, parsedData.jsonData)
encoded, err := encrypt(dbobj.masterKey, userKeyBinary, parsedData.JsonData)
if err != nil {
return "", err
}
@@ -43,17 +44,17 @@ func (dbobj dbcon) createUserRecord(parsedData userJSON, event *auditEvent) (str
// the index search field is hashed here, to be not-reversible
// I use original md5(master_key) as a kind of salt here,
// so no additional configuration field is needed here.
if len(parsedData.loginIdx) > 0 {
bdoc["loginidx"] = hashString(dbobj.hash, parsedData.loginIdx)
if len(parsedData.LoginIdx) > 0 {
bdoc["loginidx"] = utils.HashString(dbobj.hash, parsedData.LoginIdx)
}
if len(parsedData.emailIdx) > 0 {
bdoc["emailidx"] = hashString(dbobj.hash, parsedData.emailIdx)
if len(parsedData.EmailIdx) > 0 {
bdoc["emailidx"] = utils.HashString(dbobj.hash, parsedData.EmailIdx)
}
if len(parsedData.phoneIdx) > 0 {
bdoc["phoneidx"] = hashString(dbobj.hash, parsedData.phoneIdx)
if len(parsedData.PhoneIdx) > 0 {
bdoc["phoneidx"] = utils.HashString(dbobj.hash, parsedData.PhoneIdx)
}
if len(parsedData.customIdx) > 0 {
bdoc["customidx"] = hashString(dbobj.hash, parsedData.customIdx)
if len(parsedData.CustomIdx) > 0 {
bdoc["customidx"] = utils.HashString(dbobj.hash, parsedData.CustomIdx)
}
if event != nil {
event.After = encodedStr
@@ -93,7 +94,7 @@ func (dbobj dbcon) updateUserExpStatus(userTOKEN string, status string) error {
}
func (dbobj dbcon) generateTempLoginCode(userTOKEN string) int32 {
rnd := randNum(6)
rnd := utils.RandNum(6)
log.Printf("Random: %d\n", rnd)
bdoc := bson.M{}
bdoc["tempcode"] = rnd
@@ -185,7 +186,7 @@ func (dbobj dbcon) updateUserRecordDo(jsonDataPatch []byte, userTOKEN string, ol
}
oldEmail := ""
if _, ok := raw2["email"]; ok {
oldEmail = normalizeEmail(raw2["email"].(string))
oldEmail = utils.NormalizeEmail(raw2["email"].(string))
}
// merge
//log.Printf("old json: %s\n", decrypted)
@@ -221,21 +222,21 @@ func (dbobj dbcon) updateUserRecordDo(jsonDataPatch []byte, userTOKEN string, ol
actionCode := 1
newIdxFinalValue := ""
if newIdxValue, ok3 := raw[idx]; ok3 {
newIdxFinalValue = getIndexString(newIdxValue)
newIdxFinalValue = utils.GetIndexString(newIdxValue)
//log.Println("newIdxFinalValue0", newIdxFinalValue)
if len(newIdxFinalValue) > 0 {
if idx == "email" {
newIdxFinalValue = normalizeEmail(newIdxFinalValue)
newIdxFinalValue = utils.NormalizeEmail(newIdxFinalValue)
newEmail = newIdxFinalValue
} else if idx == "phone" {
newIdxFinalValue = normalizePhone(newIdxFinalValue, conf.Sms.DefaultCountry)
newIdxFinalValue = utils.NormalizePhone(newIdxFinalValue, conf.Sms.DefaultCountry)
}
}
//log.Println("newIdxFinalValue", newIdxFinalValue)
}
if idxOldValue, ok := oldUserBson[idx+"idx"]; ok {
if len(newIdxFinalValue) > 0 && len(idxOldValue.(string)) >= 0 {
idxStringHashHex := hashString(dbobj.hash, newIdxFinalValue)
idxStringHashHex := utils.HashString(dbobj.hash, newIdxFinalValue)
if idxStringHashHex == idxOldValue.(string) {
//log.Println("Index value NOT changed!")
actionCode = 0
@@ -255,7 +256,7 @@ func (dbobj dbcon) updateUserRecordDo(jsonDataPatch []byte, userTOKEN string, ol
return nil, nil, true, fmt.Errorf("duplicate %s index", idx)
}
//log.Printf("Adding index3? %s\n", raw[idx])
bdoc[idx+"idx"] = hashString(dbobj.hash, newIdxFinalValue)
bdoc[idx+"idx"] = utils.HashString(dbobj.hash, newIdxFinalValue)
} else if len(newIdxFinalValue) == 0 {
bdel = append(bdel, idx+"idx")
}
@@ -301,9 +302,9 @@ func (dbobj dbcon) lookupUserRecord(userTOKEN string) (bson.M, error) {
func (dbobj dbcon) lookupUserRecordByIndex(indexName string, indexValue string, conf Config) (bson.M, error) {
if indexName == "email" {
indexValue = normalizeEmail(indexValue)
indexValue = utils.NormalizeEmail(indexValue)
} else if indexName == "phone" {
indexValue = normalizePhone(indexValue, conf.Sms.DefaultCountry)
indexValue = utils.NormalizePhone(indexValue, conf.Sms.DefaultCountry)
}
if len(indexValue) == 0 {
return nil, nil
@@ -311,7 +312,7 @@ func (dbobj dbcon) lookupUserRecordByIndex(indexName string, indexValue string,
if indexName == "exptoken" {
return dbobj.store.GetRecord(storage.TblName.Users, "exptoken", indexValue)
}
idxStringHashHex := hashString(dbobj.hash, indexValue)
idxStringHashHex := utils.HashString(dbobj.hash, indexValue)
//log.Printf("Loading by %s, value: %s\n", indexName, indexValue)
return dbobj.store.GetRecord(storage.TblName.Users, indexName+"idx", idxStringHashHex)
}
@@ -416,7 +417,7 @@ func (dbobj dbcon) getUsers(offset int32, limit int32) ([]byte, int64, error) {
}
rec["private"] = raw2
}
expstatus := getStringValue(element["expstatus"])
expstatus := utils.GetStringValue(element["expstatus"])
if len(expstatus) > 0 {
rec["endtime"] = element["endtime"]
rec["expstatus"] = expstatus

View File

@@ -10,6 +10,7 @@ import (
"testing"
uuid "github.com/hashicorp/go-uuid"
"github.com/securitybunker/databunker/src/utils"
)
func TestUtilUUID(t *testing.T) {
@@ -18,7 +19,7 @@ func TestUtilUUID(t *testing.T) {
t.Logf("Checking[%d]: %s\n", id, recordUUID)
if err != nil {
t.Fatalf("Failed to generate UUID %s: %s ", recordUUID, err)
} else if isValidUUID(recordUUID) == false {
} else if utils.CheckValidUUID(recordUUID) == false {
t.Fatalf("Failed to validate UUID: %s ", recordUUID)
}
}
@@ -27,13 +28,13 @@ func TestUtilUUID(t *testing.T) {
func TestUtilAppNames(t *testing.T) {
goodApps := []string{"penn", "teller", "a123", "good_app"}
for _, value := range goodApps {
if isValidApp(value) == false {
if utils.CheckValidApp(value) == false {
t.Fatalf("Failed to validate good app name: %s ", value)
}
}
badApps := []string{"P1", "4as", "_a", "a.a", "a a", "a!b"}
for _, value := range badApps {
if isValidApp(value) == true {
if utils.CheckValidApp(value) == true {
t.Fatalf("Failed to validate bad app name: %s ", value)
}
}
@@ -51,7 +52,7 @@ func TestUtilStringPatternMatch(t *testing.T) {
{"pattern": "*test", "name": "123test", "result": true},
}
for _, value := range goodJsons {
if stringPatternMatch(value["pattern"].(string), value["name"].(string)) != value["result"].(bool) {
if utils.StringPatternMatch(value["pattern"].(string), value["name"].(string)) != value["result"].(bool) {
t.Fatalf("Failed in %s match %s\n", value["pattern"].(string), value["name"].(string))
}
}
@@ -67,11 +68,11 @@ func TestUtilGetJSONPost(t *testing.T) {
for _, value := range goodJsons {
request := httptest.NewRequest("POST", "/user", strings.NewReader(value))
request.Header.Set("Content-Type", "application/json")
result, err := getUserJSON(request, "IL")
result, err := utils.GetUserJSONStruct(request, "IL")
if err != nil {
t.Fatalf("Failed to parse json: %s, err: %s\n", value, err)
}
if len(result.loginIdx) == 0 {
if len(result.LoginIdx) == 0 {
t.Fatalf("Failed to parse login index from json: %s ", value)
}
}
@@ -83,11 +84,11 @@ func TestUtilGetJSONPost(t *testing.T) {
for _, value := range badJsons {
request := httptest.NewRequest("POST", "/user", strings.NewReader(value))
request.Header.Set("Content-Type", "application/json")
result, err := getUserJSON(request, "IL")
result, err := utils.GetUserJSONStruct(request, "IL")
if err != nil {
t.Fatalf("Failed to parse json: %s, err: %s\n", value, err)
}
if len(result.loginIdx) != 0 {
if len(result.LoginIdx) != 0 {
t.Fatalf("Failed to parse login index from json: %s ", value)
}
}

View File

@@ -6,6 +6,7 @@ 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"
)
@@ -28,7 +29,7 @@ func (dbobj dbcon) createRootXtoken(customRootXtoken string) (string, error) {
return "already-initialized", nil
}
if len(customRootXtoken) > 0 {
if customRootXtoken != "DEMO" && !isValidUUID(customRootXtoken) {
if customRootXtoken != "DEMO" && !utils.CheckValidUUID(customRootXtoken) {
return "", errors.New("bad root token format")
}
rootToken = customRootXtoken
@@ -39,7 +40,7 @@ func (dbobj dbcon) createRootXtoken(customRootXtoken string) (string, error) {
}
}
bdoc := bson.M{}
bdoc["xtoken"] = hashString(dbobj.hash, rootToken)
bdoc["xtoken"] = utils.HashString(dbobj.hash, rootToken)
bdoc["type"] = "root"
bdoc["token"] = ""
_, err = dbobj.store.CreateRecord(storage.TblName.Xtokens, &bdoc)
@@ -60,7 +61,7 @@ func (dbobj dbcon) generateUserLoginXtoken(userTOKEN string) (string, string, er
if err != nil {
return "", "", err
}
hashedToken := hashString(dbobj.hash, tokenUUID)
hashedToken := utils.HashString(dbobj.hash, tokenUUID)
// by default login token for 30 minutes only
expired := int32(time.Now().Unix()) + 10*60
bdoc := bson.M{}
@@ -74,10 +75,10 @@ func (dbobj dbcon) generateUserLoginXtoken(userTOKEN string) (string, string, er
func (dbobj dbcon) checkUserAuthXToken(xtokenUUID string) (tokenAuthResult, error) {
result := tokenAuthResult{}
if xtokenUUID != "DEMO" && isValidUUID(xtokenUUID) == false {
if xtokenUUID != "DEMO" && utils.CheckValidUUID(xtokenUUID) == false {
return result, errors.New("failed to authenticate")
}
xtokenHashed := hashString(dbobj.hash, xtokenUUID)
xtokenHashed := utils.HashString(dbobj.hash, xtokenUUID)
if len(rootXTOKEN) > 0 && rootXTOKEN == xtokenHashed {
//log.Println("It is a root token")
result.ttype = "root"