new session code

This commit is contained in:
root
2020-11-24 21:44:27 +00:00
parent 7820cebcae
commit 7be688baee
7 changed files with 108 additions and 40 deletions

View File

@@ -109,6 +109,7 @@ type userJSON struct {
loginIdx string
emailIdx string
phoneIdx string
token string
}
type tokenAuthResult struct {
@@ -218,7 +219,9 @@ func (e mainEnv) setupRouter() *httprouter.Router {
router.GET("/v1/userapp/token/:token", e.userappList)
router.GET("/v1/userapps", e.appList)
router.POST("/v1/session/:mode/:address", e.newSession)
router.GET("/v1/session/:session", e.getSession)
router.POST("/v1/session/:session", e.createSession)
router.POST("/v1/session/:mode/:address", e.newUserSession)
router.GET("/v1/session/:mode/:address", e.getUserSessions)
router.GET("/v1/metrics", e.metrics)

View File

@@ -6,13 +6,70 @@ import (
"net/http"
"reflect"
"strings"
uuid "github.com/hashicorp/go-uuid"
"github.com/julienschmidt/httprouter"
"github.com/paranoidguy/databunker/src/storage"
"go.mongodb.org/mongo-driver/bson"
)
func (e mainEnv) newSession(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
func (e mainEnv) createSession(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
session := ps.ByName("session")
event := audit("create session", session, "session", session)
defer func() { event.submit(e.db) }()
if enforceUUID(w, session, event) == false {
//returnError(w, r, "bad session format", nil, event)
return
}
authResult := e.enforceAdmin(w, r)
if authResult == "" {
return
}
expiration := e.conf.Policy.MaxSessionRetentionPeriod
parsedData, err := getJSONPost(r, e.conf.Sms.DefaultCountry)
if err != nil {
returnError(w, r, "failed to decode request body", 405, err, event)
return
}
if len(parsedData.jsonData) == 0 {
returnError(w, r, "empty request body", 405, nil, event)
return
}
var userBson bson.M
if len(parsedData.loginIdx) > 0 {
userBson, err = e.db.lookupUserRecordByIndex("login", parsedData.loginIdx, e.conf)
} else if len(parsedData.emailIdx) > 0 {
userBson, err = e.db.lookupUserRecordByIndex("email", parsedData.emailIdx, e.conf)
} else if len(parsedData.phoneIdx) > 0 {
userBson, err = e.db.lookupUserRecordByIndex("phone", parsedData.phoneIdx, e.conf)
} else if len(parsedData.token) > 0 {
userBson, err = e.db.lookupUserRecord(parsedData.token)
}
if err != nil {
returnError(w, r, "internal error", 405, err, event)
return
}
userTOKEN := ""
if userBson != nil {
userTOKEN = userBson["token"].(string)
event.Record = userTOKEN
}
sessionUUID, err := uuid.GenerateUUID()
if err != nil {
returnError(w, r, "internal error", 405, err, event)
return
}
sessionID, err := e.db.createSessionRecord(sessionUUID, userTOKEN, expiration, parsedData.jsonData)
if err != nil {
returnError(w, r, "internal error", 405, err, event)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(200)
fmt.Fprintf(w, `{"status":"ok","session":"%s"}`, sessionID)
return
}
func (e mainEnv) newUserSession(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
address := ps.ByName("address")
mode := ps.ByName("mode")
event := audit("create user session", address, mode, address)
@@ -66,7 +123,12 @@ func (e mainEnv) newSession(w http.ResponseWriter, r *http.Request, ps httproute
returnError(w, r, "internal error", 405, err, event)
return
}
sessionID, err := e.db.createSessionRecord(userTOKEN, expiration, jsonData)
sessionUUID, err := uuid.GenerateUUID()
if err != nil {
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)
return
@@ -80,12 +142,6 @@ 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) {
address := ps.ByName("address")
mode := ps.ByName("mode")
if mode == "session" {
e.db.store.DeleteExpired(storage.TblName.Sessions, "session", address)
e.getSession(w, r, address)
return
}
event := audit("get all user sessions", address, mode, address)
defer func() { event.submit(e.db) }()
@@ -137,16 +193,19 @@ func (e mainEnv) getUserSessions(w http.ResponseWriter, r *http.Request, ps http
return
}
func (e mainEnv) getSession(w http.ResponseWriter, r *http.Request, session string) {
func (e mainEnv) getSession(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
session := ps.ByName("session")
event := audit("get session", session, "session", session)
defer func() { event.submit(e.db) }()
when, record, userTOKEN, err := e.db.getUserSession(session)
when, record, userTOKEN, err := e.db.getSession(session)
if err != nil {
returnError(w, r, err.Error(), 405, err, event)
return
}
event.Record = userTOKEN
if len(userTOKEN) > 0 {
event.Record = userTOKEN
}
if e.enforceAuth(w, r, event) == "" {
return
}

View File

@@ -6,7 +6,6 @@ import (
"fmt"
"time"
uuid "github.com/hashicorp/go-uuid"
"github.com/paranoidguy/databunker/src/storage"
"go.mongodb.org/mongo-driver/bson"
)
@@ -16,7 +15,7 @@ type sessionEvent struct {
Data string `json:"data"`
}
func (dbobj dbcon) createSessionRecord(userTOKEN string, expiration string, data []byte) (string, error) {
func (dbobj dbcon) createSessionRecord(sessionUUID string, userTOKEN string, expiration string, data []byte) (string, error) {
var endtime int32
var err error
if len(expiration) > 0 {
@@ -25,14 +24,15 @@ func (dbobj dbcon) createSessionRecord(userTOKEN string, expiration string, data
return "", err
}
}
encodedStr, err := dbobj.userEncrypt(userTOKEN, data)
recordKey, err := generateRecordKey()
if err != nil {
return "", err
}
sessionUUID, err := uuid.GenerateUUID()
encoded, err := encrypt(dbobj.masterKey, recordKey, data)
if err != nil {
return "", err
}
encodedStr := base64.StdEncoding.EncodeToString(encoded)
bdoc := bson.M{}
now := int32(time.Now().Unix())
bdoc["token"] = userTOKEN
@@ -40,14 +40,20 @@ func (dbobj dbcon) createSessionRecord(userTOKEN string, expiration string, data
bdoc["endtime"] = endtime
bdoc["when"] = now
bdoc["data"] = encodedStr
_, err = dbobj.store.CreateRecord(storage.TblName.Sessions, &bdoc)
if err != nil {
return "", err
bdoc["key"] = base64.StdEncoding.EncodeToString(recordKey)
record, err := dbobj.store.GetRecord(storage.TblName.Sessions, "session", sessionUUID)
if record == nil || len(record) == 0 {
_, err = dbobj.store.CreateRecord(storage.TblName.Sessions, &bdoc)
if err != nil {
return "", err
}
return sessionUUID, nil
}
dbobj.store.UpdateRecord(storage.TblName.Sessions, "session", sessionUUID, &bdoc)
return sessionUUID, nil
}
func (dbobj dbcon) getUserSession(sessionUUID string) (int32, []byte, string, error) {
func (dbobj dbcon) getSession(sessionUUID string) (int32, []byte, string, error) {
record, err := dbobj.store.GetRecord(storage.TblName.Sessions, "session", sessionUUID)
if err != nil {
return 0, nil, "", err
@@ -63,41 +69,38 @@ func (dbobj dbcon) getUserSession(sessionUUID string) (int32, []byte, string, er
when := record["when"].(int32)
userTOKEN := record["token"].(string)
encData0 := record["data"].(string)
decrypted, err := dbobj.userDecrypt(userTOKEN, encData0)
recordKey0 := record["key"].(string)
recordKey, err := base64.StdEncoding.DecodeString(recordKey0)
if err != nil {
return 0, nil, "", err
return 0, nil, "", err
}
encData, err := base64.StdEncoding.DecodeString(encData0)
if err != nil {
return 0, nil, "", err
}
decrypted, err := decrypt(dbobj.masterKey, recordKey, encData)
if err != nil {
return 0, nil, "", err
}
return when, decrypted, userTOKEN, err
}
func (dbobj dbcon) getUserSessionsByToken(userTOKEN string, offset int32, limit int32) ([]string, int64, error) {
userBson, err := dbobj.lookupUserRecord(userTOKEN)
if userBson == nil || err != nil {
// not found
return nil, 0, err
}
userKey := userBson["key"].(string)
recordKey, err := base64.StdEncoding.DecodeString(userKey)
if err != nil {
return nil, 0, err
}
count, err := dbobj.store.CountRecords(storage.TblName.Sessions, "token", userTOKEN)
if err != nil {
return nil, 0, err
}
records, err := dbobj.store.GetList(storage.TblName.Sessions, "token", userTOKEN, offset, limit, "")
if err != nil {
return nil, 0, err
}
var results []string
for _, element := range records {
when := element["when"].(int32)
session := element["session"].(string)
encData0 := element["data"].(string)
recordKey0 := element["key"].(string)
recordKey, _ := base64.StdEncoding.DecodeString(recordKey0)
encData, _ := base64.StdEncoding.DecodeString(encData0)
decrypted, _ := decrypt(dbobj.masterKey, recordKey, encData)
sEvent := fmt.Sprintf(`{"when":%d,"session":"%s","data":%s}`, when, session, string(decrypted))

View File

@@ -106,7 +106,7 @@ func (e mainEnv) getRecord(w http.ResponseWriter, r *http.Request, ps httprouter
if len(recordInfo.appName) > 0 {
resultJSON, err = e.db.getUserApp(recordInfo.token, recordInfo.appName)
} else if len(recordInfo.session) > 0 {
_, resultJSON, _, err = e.db.getUserSession(recordInfo.session)
_, resultJSON, _, err = e.db.getSession(recordInfo.session)
} else {
resultJSON, err = e.db.getUser(recordInfo.token)
}

View File

@@ -1075,6 +1075,7 @@ func (dbobj MySQLDB) initSessions() error {
`CREATE TABLE IF NOT EXISTS sessions (`+
`token TINYTEXT,`+
`session TINYTEXT,`+
"`key` TINYTEXT,"+
`data TEXT,`+
`endtime int,`+
"`when` int);",

View File

@@ -1059,6 +1059,7 @@ func (dbobj SQLiteDB) initSessions() error {
queries := []string{`CREATE TABLE IF NOT EXISTS sessions (
token STRING,
session STRING,
key STRING,
data TEXT,
endtime int,
` + "`when` int);",

View File

@@ -523,9 +523,10 @@ func getJSONPost(r *http.Request, defaultCountry string) (userJSON, error) {
if value, ok := records["phone"]; ok {
result.phoneIdx = normalizePhone(getIndexString(value), defaultCountry)
}
if value, ok := records["token"]; ok {
result.token = value.(string)
}
result.jsonData, err = json.Marshal(records)
return result, err
}