mirror of
https://github.com/optim-enterprises-bv/databunker.git
synced 2025-11-02 02:48:05 +00:00
audit event drill down
This commit is contained in:
@@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/julienschmidt/httprouter"
|
"github.com/julienschmidt/httprouter"
|
||||||
@@ -37,6 +38,32 @@ func (e mainEnv) getAuditEvents(w http.ResponseWriter, r *http.Request, ps httpr
|
|||||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
w.WriteHeader(200)
|
w.WriteHeader(200)
|
||||||
str := fmt.Sprintf(`{"total":%d,"rows":%s}`, counter, resultJSON)
|
str := fmt.Sprintf(`{"status":"ok","total":%d,"rows":%s}`, counter, resultJSON)
|
||||||
|
w.Write([]byte(str))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e mainEnv) getAuditEvent(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||||
|
atoken := ps.ByName("atoken")
|
||||||
|
event := audit("view audit event", atoken, "token", atoken)
|
||||||
|
defer func() { event.submit(e.db) }()
|
||||||
|
//fmt.Println("error code")
|
||||||
|
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)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
event.Record = userTOKEN
|
||||||
|
if e.enforceAuth(w, r, event) == false {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//fmt.Fprintf(w, "<html><head><title>title</title></head>")
|
||||||
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
|
w.WriteHeader(200)
|
||||||
|
str := fmt.Sprintf(`{"status":"ok","event":%s}`, resultJSON)
|
||||||
w.Write([]byte(str))
|
w.Write([]byte(str))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
uuid "github.com/hashicorp/go-uuid"
|
uuid "github.com/hashicorp/go-uuid"
|
||||||
@@ -104,3 +105,55 @@ func (dbobj dbcon) getAuditEvents(userTOKEN string, offset int32, limit int32) (
|
|||||||
//fmt.Printf("Found multiple documents (array of pointers): %+v\n", results)
|
//fmt.Printf("Found multiple documents (array of pointers): %+v\n", results)
|
||||||
return resultJSON, count, nil
|
return resultJSON, count, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (dbobj dbcon) getAuditEvent(atoken string) (string, []byte, error) {
|
||||||
|
//var results []*auditEvent
|
||||||
|
record, err := dbobj.getRecord(TblName.Audit, "atoken", atoken)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
fmt.Printf("audit record: %s\n", record)
|
||||||
|
before := ""
|
||||||
|
after := ""
|
||||||
|
debug := ""
|
||||||
|
if value, ok := record["before"]; ok {
|
||||||
|
before = value.(string)
|
||||||
|
}
|
||||||
|
if value, ok := record["after"]; ok {
|
||||||
|
after = value.(string)
|
||||||
|
}
|
||||||
|
if value, ok := record["debug"]; ok {
|
||||||
|
debug = value.(string)
|
||||||
|
}
|
||||||
|
//recBson := bson.M{}
|
||||||
|
userTOKEN := ""
|
||||||
|
if value, ok := record["record"]; ok {
|
||||||
|
userTOKEN = value.(string)
|
||||||
|
if len(userTOKEN) > 0 {
|
||||||
|
if len(before) > 0 {
|
||||||
|
before2, after2, _ := dbobj.userDecrypt2(userTOKEN, before, after)
|
||||||
|
log.Printf("before: %s", before2)
|
||||||
|
log.Printf("after: %s", after2)
|
||||||
|
record["before"] = before2
|
||||||
|
record["after"] = after2
|
||||||
|
if len(debug) == 0 {
|
||||||
|
result := fmt.Sprintf(`{"before":%s,"after":%s}`, before2, after2)
|
||||||
|
return userTOKEN, []byte(result), nil
|
||||||
|
}
|
||||||
|
result := fmt.Sprintf(`{"before":%s,"after":%s,"debug":%s}`, before2, after2, debug)
|
||||||
|
return userTOKEN, []byte(result), nil
|
||||||
|
} else if len(after) > 0 {
|
||||||
|
after2, _ := dbobj.userDecrypt(userTOKEN, after)
|
||||||
|
log.Printf("after: %s", after2)
|
||||||
|
record["after"] = after2
|
||||||
|
result := fmt.Sprintf(`{"after":%s,"debug":%s}`, after2, debug)
|
||||||
|
return userTOKEN, []byte(result), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(debug) > 0 {
|
||||||
|
result := fmt.Sprintf(`{"debug":%s}`, debug)
|
||||||
|
return userTOKEN, []byte(result), nil
|
||||||
|
}
|
||||||
|
return userTOKEN, nil, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -167,7 +167,8 @@ func (e mainEnv) setupRouter() *httprouter.Router {
|
|||||||
router.GET("/v1/metrics", e.metrics)
|
router.GET("/v1/metrics", e.metrics)
|
||||||
|
|
||||||
router.GET("/v1/audit/list/:token", e.getAuditEvents)
|
router.GET("/v1/audit/list/:token", e.getAuditEvents)
|
||||||
|
router.GET("/v1/audit/get/:atoken", e.getAuditEvent)
|
||||||
|
|
||||||
router.GET("/", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
router.GET("/", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||||
data, err := box.Find("index.html")
|
data, err := box.Find("index.html")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -416,3 +416,33 @@ func (dbobj dbcon) userDecrypt(userTOKEN, src string) ([]byte, error) {
|
|||||||
decrypted, err := decrypt(dbobj.masterKey, recordKey, encData)
|
decrypted, err := decrypt(dbobj.masterKey, recordKey, encData)
|
||||||
return decrypted, err
|
return decrypted, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (dbobj dbcon) userDecrypt2(userTOKEN, src string, src2 string) ([]byte, []byte, error) {
|
||||||
|
userBson, err := dbobj.lookupUserRecord(userTOKEN)
|
||||||
|
if err != nil {
|
||||||
|
// not found
|
||||||
|
return nil, nil, errors.New("not found")
|
||||||
|
}
|
||||||
|
if userBson == nil {
|
||||||
|
return nil, nil, errors.New("not found")
|
||||||
|
}
|
||||||
|
userKey := userBson["key"].(string)
|
||||||
|
recordKey, err := base64.StdEncoding.DecodeString(userKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
encData, err := base64.StdEncoding.DecodeString(src)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
decrypted, err := decrypt(dbobj.masterKey, recordKey, encData)
|
||||||
|
if len(src2) == 0 {
|
||||||
|
return decrypted, nil, err
|
||||||
|
}
|
||||||
|
encData2, err := base64.StdEncoding.DecodeString(src2)
|
||||||
|
if err != nil {
|
||||||
|
return decrypted, nil, err
|
||||||
|
}
|
||||||
|
decrypted2, err := decrypt(dbobj.masterKey, recordKey, encData2)
|
||||||
|
return decrypted, decrypted2, err
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,11 +24,72 @@
|
|||||||
<script src="https://unpkg.com/bootstrap-table@1.15.5/dist/bootstrap-table.min.js"></script>
|
<script src="https://unpkg.com/bootstrap-table@1.15.5/dist/bootstrap-table.min.js"></script>
|
||||||
<script src="https://unpkg.com/bootstrap-table@1.15.5/dist/bootstrap-table.min.js"></script>
|
<script src="https://unpkg.com/bootstrap-table@1.15.5/dist/bootstrap-table.min.js"></script>
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/json.min.js"></script>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/styles/a11y-dark.min.css">
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
var xtoken = window.localStorage.getItem('xtoken');
|
||||||
|
var token = window.localStorage.getItem('token');
|
||||||
|
function displayDrillDownLink(atoken, row, index) {
|
||||||
|
return '<a href=\'javascript:displayAudit(\"' + atoken + '\");\'>*</a>';
|
||||||
|
}
|
||||||
|
function displayAudit(atoken) {
|
||||||
|
var xhr0 = new XMLHttpRequest();
|
||||||
|
// first save consent
|
||||||
|
xhr0.open('GET', '/v1/audit/get/' + atoken, false);
|
||||||
|
xhr0.setRequestHeader("X-Bunker-Token", xtoken)
|
||||||
|
xhr0.setRequestHeader('Content-type', 'application/json');
|
||||||
|
xhr0.onload = function () {
|
||||||
|
if (xhr0.status === 200) {
|
||||||
|
console.log(xhr0.responseText);
|
||||||
|
//$('#drilldown').html(xhr0.responseText)
|
||||||
|
//$('#drilldown').append("HELLO");
|
||||||
|
var data = JSON.parse(xhr0.responseText);
|
||||||
|
if (data.status == "ok") {
|
||||||
|
var d = JSON.stringify(data.event, null, 4);
|
||||||
|
setTimeout(function () {
|
||||||
|
$('#drilldown').append('<code class="json">' + d + '</code>');
|
||||||
|
document.querySelectorAll('pre code').forEach((block) => {
|
||||||
|
hljs.highlightBlock(block);
|
||||||
|
});
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xhr0.send();
|
||||||
|
|
||||||
|
var heading = "Audit drill down";
|
||||||
|
var text = "Display audit event: " + atoken;
|
||||||
|
var cancelButtonTxt = "Close popup";
|
||||||
|
var confirmModal =
|
||||||
|
$('<div class="modal fade" role="dialog"><div class="modal-dialog" role="document"><div class="modal-content">' +
|
||||||
|
'<div class="modal-header">' +
|
||||||
|
'<h5 class="modal-title">' + heading + '</h5>' +
|
||||||
|
'<button type="button" class="close" data-dismiss="modal" aria-label="Close">' +
|
||||||
|
'<span aria-hidden="true">×</span></button>' +
|
||||||
|
'</div>' +
|
||||||
|
'<div class="modal-body">' +
|
||||||
|
'<p>' + text + '</p>' +
|
||||||
|
'<pre id="drilldown"></pre>' +
|
||||||
|
'</div>' +
|
||||||
|
'<div class="modal-footer">' +
|
||||||
|
'<a href="#" class="btn" data-dismiss="modal">' +
|
||||||
|
cancelButtonTxt +
|
||||||
|
'</a>' +
|
||||||
|
'</div>' +
|
||||||
|
'</div></div></div>');
|
||||||
|
|
||||||
|
confirmModal.find('#okButton').click(function (event) {
|
||||||
|
//callback();
|
||||||
|
//cancelConsent(brief);
|
||||||
|
confirmModal.modal('hide');
|
||||||
|
});
|
||||||
|
|
||||||
|
confirmModal.modal('show');
|
||||||
|
}
|
||||||
|
|
||||||
$(function () {
|
$(function () {
|
||||||
var xtoken = window.localStorage.getItem('xtoken');
|
|
||||||
var token = window.localStorage.getItem('token');
|
|
||||||
var ttype = window.localStorage.getItem('type');
|
|
||||||
//$('#msg').text("Loading data")
|
//$('#msg').text("Loading data")
|
||||||
//token = "faa006da-475e-45c6-a4a1-6586dce8b8d2";
|
//token = "faa006da-475e-45c6-a4a1-6586dce8b8d2";
|
||||||
$('#table').bootstrapTable({
|
$('#table').bootstrapTable({
|
||||||
@@ -93,6 +154,7 @@
|
|||||||
<th scope="col" data-field="title">Title</th>
|
<th scope="col" data-field="title">Title</th>
|
||||||
<th scope="col" data-field="status">Status</th>
|
<th scope="col" data-field="status">Status</th>
|
||||||
<th scope="col" data-field="msg">Msg</th>
|
<th scope="col" data-field="msg">Msg</th>
|
||||||
|
<th scope="col" data-field="atoken" data-formatter="displayDrillDownLink">More</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
Reference in New Issue
Block a user