add session API

This commit is contained in:
stremovsky
2019-12-16 22:15:22 +02:00
parent e9693ca98f
commit 6954850ffb
4 changed files with 52 additions and 24 deletions

View File

@@ -1,5 +1,4 @@
#!/bin/sh #!/bin/sh
set -x
DATABUNKER_APIKEY=$1 DATABUNKER_APIKEY=$1
if [ -z $DATABUNKER_APIKEY ]; then if [ -z $DATABUNKER_APIKEY ]; then
@@ -61,3 +60,21 @@ echo "View all user consents: $RESULT"
RESULT=`curl -s http://localhost:3000/v1/consents/send-sms \ RESULT=`curl -s http://localhost:3000/v1/consents/send-sms \
-H "X-Bunker-Token: "$DATABUNKER_APIKEY -H "Content-Type: application/json"` -H "X-Bunker-Token: "$DATABUNKER_APIKEY -H "Content-Type: application/json"`
echo "View all users with send-sms consent on: $RESULT" echo "View all users with send-sms consent on: $RESULT"
RESULT=`curl -s http://localhost:3000/v1/session/token/$TOKEN -XPOST \
-H "X-Bunker-Token: "$DATABUNKER_APIKEY -H "Content-Type: application/json" \
-d '{"clientip":"1.1.1.1","x-forwarded-for":"2.2.2.2"}'`
echo "Create session 1: $RESULT"
RESULT=`curl -s http://localhost:3000/v1/session/email/test@paranoidguy.com -XPOST \
-H "X-Bunker-Token: "$DATABUNKER_APIKEY -H "Content-Type: application/json" \
-d '{"clientip":"1.1.1.1","x-forwarded-for":"2.2.2.2","info":"email"}'`
echo "Create session 1: $RESULT"
RESULT=`curl -s http://localhost:3000/v1/session/session/7a77ffad-2010-4e47-abbe-bcd04509f784 \
-H "X-Bunker-Token: "$DATABUNKER_APIKEY -H "Content-Type: application/json"`
echo "Get session: $RESULT"
RESULT=`curl -s http://localhost:3000/v1/session/phone/4444 \
-H "X-Bunker-Token: "$DATABUNKER_APIKEY -H "Content-Type: application/json"`
echo "Get sessions: $RESULT"

View File

@@ -148,6 +148,9 @@ func (e mainEnv) setupRouter() *httprouter.Router {
router.GET("/v1/userapp/token/:token", e.userappList) router.GET("/v1/userapp/token/:token", e.userappList)
router.GET("/v1/userapps", e.appList) router.GET("/v1/userapps", e.appList)
router.POST("/v1/session/:mode/:address", e.newSession)
router.GET("/v1/session/:mode/:address", e.getUserSessions)
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)

View File

@@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"reflect" "reflect"
"strings"
"github.com/julienschmidt/httprouter" "github.com/julienschmidt/httprouter"
) )
@@ -40,7 +41,7 @@ func (e mainEnv) newSession(w http.ResponseWriter, r *http.Request, ps httproute
return return
} }
} }
expiration := "" expiration := "1d"
records, err := getJSONPostData(r) records, err := getJSONPostData(r)
if err != nil { 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)
@@ -77,6 +78,10 @@ func (e mainEnv) newSession(w http.ResponseWriter, r *http.Request, ps httproute
func (e mainEnv) getUserSessions(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { func (e mainEnv) getUserSessions(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
address := ps.ByName("address") address := ps.ByName("address")
mode := ps.ByName("mode") mode := ps.ByName("mode")
if mode == "session" {
e.getSession(w, r, address)
return
}
event := audit("get all user sessions", address, mode, address) event := audit("get all user sessions", address, mode, address)
defer func() { event.submit(e.db) }() defer func() { event.submit(e.db) }()
@@ -110,29 +115,29 @@ func (e mainEnv) getUserSessions(w http.ResponseWriter, r *http.Request, ps http
returnError(w, r, "internal error", 405, err, event) returnError(w, r, "internal error", 405, err, event)
return return
} }
resultJSON, err := json.Marshal(records) data := strings.Join(records, ",")
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)
fmt.Fprintf(w, `{"status":"ok","count":"%d","rows":"%"}`, count, resultJSON) fmt.Fprintf(w, `{"status":"ok","count":"%d","rows":%s}`, count, data)
return return
} }
func (e mainEnv) getSession(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { func (e mainEnv) getSession(w http.ResponseWriter, r *http.Request, session string) {
session := ps.ByName("session")
event := audit("get session", session, "session", session) event := audit("get session", session, "session", session)
defer func() { event.submit(e.db) }() defer func() { event.submit(e.db) }()
if e.enforceAuth(w, r, event) == false { if e.enforceAuth(w, r, event) == false {
return return
} }
record, userTOKEN, err := e.db.getUserSession(session) when, record, userTOKEN, err := e.db.getUserSession(session)
if err != nil { if err != nil {
returnError(w, r, "internal error", 405, err, event) fmt.Printf("error: %s\n", err)
returnError(w, r, err.Error(), 405, err, event)
return return
} }
event.Record = userTOKEN event.Record = userTOKEN
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)
fmt.Fprintf(w, `{"status":"ok","session":"%s","data":"%"}`, session, record) fmt.Fprintf(w, `{"status":"ok","session":"%s","when":%d,"data":%s}`, session, when, record)
return return
} }

View File

@@ -3,6 +3,7 @@ package main
import ( import (
"encoding/base64" "encoding/base64"
"errors" "errors"
"fmt"
"time" "time"
uuid "github.com/hashicorp/go-uuid" uuid "github.com/hashicorp/go-uuid"
@@ -10,8 +11,8 @@ import (
) )
type sessionEvent struct { type sessionEvent struct {
When int32 When int32 `json:"when"`
Data string Data string `json:"data"`
} }
func (dbobj dbcon) createSessionRecord(userTOKEN string, expiration string, data []byte) (string, error) { func (dbobj dbcon) createSessionRecord(userTOKEN string, expiration string, data []byte) (string, error) {
@@ -27,14 +28,14 @@ func (dbobj dbcon) createSessionRecord(userTOKEN string, expiration string, data
if err != nil { if err != nil {
return "", err return "", err
} }
tokenUUID, err := uuid.GenerateUUID() sessionUUID, err := uuid.GenerateUUID()
if err != nil { if err != nil {
return "", err return "", err
} }
bdoc := bson.M{} bdoc := bson.M{}
now := int32(time.Now().Unix()) now := int32(time.Now().Unix())
bdoc["token"] = userTOKEN bdoc["token"] = userTOKEN
bdoc["session"] = tokenUUID bdoc["session"] = sessionUUID
bdoc["endtime"] = endtime bdoc["endtime"] = endtime
bdoc["when"] = now bdoc["when"] = now
bdoc["data"] = encodedStr bdoc["data"] = encodedStr
@@ -42,32 +43,33 @@ func (dbobj dbcon) createSessionRecord(userTOKEN string, expiration string, data
if err != nil { if err != nil {
return "", err return "", err
} }
return tokenUUID, nil return sessionUUID, nil
} }
func (dbobj dbcon) getUserSession(sessionUUID string) ([]byte, string, error) { func (dbobj dbcon) getUserSession(sessionUUID string) (int32, []byte, string, error) {
record, err := dbobj.getRecord(TblName.Sessions, "session", sessionUUID) record, err := dbobj.getRecord(TblName.Sessions, "session", sessionUUID)
if err != nil { if err != nil {
return nil, "", err return 0, nil, "", err
} }
if record == nil { if record == nil {
return nil, "", errors.New("not found") return 0, nil, "", errors.New("not found")
} }
// check expiration // check expiration
now := int32(time.Now().Unix()) now := int32(time.Now().Unix())
if now > record["endtime"].(int32) { if now > record["endtime"].(int32) {
return nil, "", errors.New("session expired") return 0, nil, "", errors.New("session expired")
} }
when := record["when"].(int32)
userTOKEN := record["token"].(string) userTOKEN := record["token"].(string)
encData0 := record["data"].(string) encData0 := record["data"].(string)
decrypted, err := dbobj.userDecrypt(userTOKEN, encData0) decrypted, err := dbobj.userDecrypt(userTOKEN, encData0)
if err != nil { if err != nil {
return nil, "", err return 0, nil, "", err
} }
return decrypted, userTOKEN, err return when, decrypted, userTOKEN, err
} }
func (dbobj dbcon) getUserSessionByToken(userTOKEN string) ([]*sessionEvent, int64, error) { func (dbobj dbcon) getUserSessionByToken(userTOKEN string) ([]string, int64, error) {
userBson, err := dbobj.lookupUserRecord(userTOKEN) userBson, err := dbobj.lookupUserRecord(userTOKEN)
if userBson == nil || err != nil { if userBson == nil || err != nil {
@@ -90,13 +92,14 @@ func (dbobj dbcon) getUserSessionByToken(userTOKEN string) ([]*sessionEvent, int
return nil, 0, err return nil, 0, err
} }
var results []*sessionEvent var results []string
for _, element := range records { for _, element := range records {
when := element["when"].(int32)
encData0 := element["data"].(string) encData0 := element["data"].(string)
encData, _ := base64.StdEncoding.DecodeString(encData0) encData, _ := base64.StdEncoding.DecodeString(encData0)
decrypted, _ := decrypt(dbobj.masterKey, recordKey, encData) decrypted, _ := decrypt(dbobj.masterKey, recordKey, encData)
sEvent := sessionEvent{0, string(decrypted)} sEvent := fmt.Sprintf(`{"when":%d,"data":%s}`, when, string(decrypted))
results = append(results, &sEvent) results = append(results, sEvent)
} }
return results, count, err return results, count, err