-
Kunal Taitkar authored2e569d57
routebuilder_fasthttp.go 10.43 KiB
// +build fasthttp
package routebuildermdl
import (
"context"
"coresls/servers/coresls/app/modules/constantmdl"
"strings"
"github.com/pquerna/ffjson/ffjson"
routing "github.com/qiangxue/fasthttp-routing"
"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/statemdl"
"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/authmdl/jwtmdl"
"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/authmdl/roleenforcemdl"
"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/errormdl"
"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/loggermdl"
"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/servicebuildermdl"
version "github.com/hashicorp/go-version"
"github.com/tidwall/gjson"
)
// Init routing init
func Init(o, r, c *routing.RouteGroup, JWTKey string) {
o.Post("/mql/state", statemdl.StateHandler)
o.Post("/mql", OpenHandler)
r.Post("/mql", RestrictedHandler)
c.Post("/mql", RoleBasedHandler)
o.Post("/heavymql", HeavyOpenHandler)
r.Post("/heavymql", HeavyRestrictedHandler)
c.Post("/heavymql", HeavyRoleBasedHandler)
jwtmdl.GlobalJWTKey = JWTKey
}
func commonHandler(c *routing.Context, isRestricted, isRoleBased, heavyDataActivity bool, principalObj servicebuildermdl.Principal) error {
serviceHeader := string(c.Request.Header.Peek("Service-Header"))
services := strings.Split(serviceHeader, ",")
versionError := appVersioning(c)
if versionError != nil {
_, err := c.WriteString(versionError.Error())
c.SetStatusCode(417)
return err
}
responseMap := make(map[string]responseData)
var reqBody []byte
reqBody = c.Request.Body()
requestBody := gjson.ParseBytes(reqBody)
for i := 0; i < len(services); i++ {
responseDataObj := responseData{}
service := services[i]
result, ab, isCompressed, errorCode, err := executeService(service, []byte(requestBody.Get(service).String()), isRestricted, isRoleBased, heavyDataActivity, principalObj)
if errormdl.CheckErr1(err) != nil {
if ab == nil {
responseDataObj.ErrorCode = errorCode
responseDataObj.Error = err.Error()
} else {
responseDataObj.Error = ab.GetErrorData()
if responseDataObj.Error == nil {
responseDataObj.Error = err.Error()
}
errorCode := ab.GetErrorCode()
if errorCode == 0 {
errorCode = errormdl.EXPECTATIONFAILED
}
responseDataObj.ErrorCode = errorCode
if ab.TransactionEnable {
loggermdl.LogError("transaction enabled rollback")
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
var err error
// database transaction rollback if transaction is enabled
switch ab.DatabaseType {
case constantmdl.MYSQL:
if ab.TXN != nil {
loggermdl.LogError("MYSQL Transaction Rollbacked")
err = ab.TXN.Rollback()
if err != nil {
responseDataObj.Error = err.Error()
responseDataObj.ErrorCode = errormdl.MYSQLERROR
}
}
case constantmdl.SQLSERVER:
if ab.SQLServerTXN != nil {
loggermdl.LogError("SQLSERVER Transaction Rollbacked")
err = ab.SQLServerTXN.Rollback()
if err != nil {
responseDataObj.Error = err.Error()
responseDataObj.ErrorCode = errormdl.MYSQLERROR
}
}
case constantmdl.GraphDB:
if ab.GraphDbTXN != nil {
loggermdl.LogError("GRAPHDB Transaction Rollbacked")
err = ab.GraphDbTXN.Discard(context.TODO())
if err != nil {
responseDataObj.Error = err.Error()
responseDataObj.ErrorCode = errormdl.GRAPHDBERROR
}
}
default:
loggermdl.LogError("Invalid database type while rollback transaction")
}
}
}
} else {
if ab != nil {
if ab.TransactionEnable {
var err error
switch ab.DatabaseType {
case constantmdl.MYSQL:
if ab.TXN != nil {
loggermdl.LogError("MYSQL Transaction Commit")
err = ab.TXN.Commit()
if err != nil {
responseDataObj.Error = err.Error()
responseDataObj.ErrorCode = errormdl.MYSQLERROR
} else {
responseDataObj.Result = result
responseDataObj.ErrorCode = errormdl.NOERROR
}
}
case constantmdl.SQLSERVER:
if ab.SQLServerTXN != nil {
loggermdl.LogError("SQLSERVER Transaction Commit")
err = ab.SQLServerTXN.Commit()
if err != nil {
responseDataObj.Error = err.Error()
responseDataObj.ErrorCode = errormdl.SQLSERVERERROR
} else {
responseDataObj.Result = result
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
responseDataObj.ErrorCode = errormdl.NOERROR
}
}
case constantmdl.GraphDB:
if ab.SQLServerTXN != nil {
loggermdl.LogError("GRAPHDB Transaction Commit")
err = ab.GraphDbTXN.Commit(context.TODO())
if err != nil {
responseDataObj.Error = err.Error()
responseDataObj.ErrorCode = errormdl.GRAPHDBERROR
} else {
responseDataObj.Result = result
responseDataObj.ErrorCode = errormdl.NOERROR
}
}
default:
loggermdl.LogError("Invalid database type while commit transaction")
}
} else {
responseDataObj.Result = result
responseDataObj.ErrorCode = errormdl.NOERROR
}
} else {
responseDataObj.Result = result
responseDataObj.ErrorCode = errormdl.NOERROR
}
}
responseDataObj.IsCompressed = isCompressed
responseDataObj = formatResponse(ab, responseDataObj)
responseMap[service] = responseDataObj
// Token extraction
// if ab != nil {
// token, ok := ab.GetDataString("MQLToken")
// if !ok {
// token = string(c.Request.Header.Peek("Authorization"))
// token = strings.TrimPrefix(token, "Bearer")
// token = strings.TrimSpace(token)
// c.Response.Header.Set("Authorization", token)
// }
// c.Response.Header.Set("Authorization", token)
// } else {
// token := string(c.Request.Header.Peek("Authorization"))
// token = strings.TrimPrefix(token, "Bearer")
// token = strings.TrimSpace(token)
// c.Response.Header.Set("Authorization", token)
// }
if ab != nil {
token, ok := ab.GetDataString("MQLToken")
if ok {
c.Response.Header.Set("Authorization", token)
}
}
}
ba, _ := ffjson.Marshal(responseMap)
_, err := c.Write(ba)
c.SetStatusCode(200)
return err
}
// OpenHandler for /o
func OpenHandler(c *routing.Context) error {
c.Response.Header.Set("content-type", "application/json")
principal := servicebuildermdl.Principal{}
principal.ClientIP = c.RemoteIP().String()
commonHandler(c, false, false, false, principal)
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
return nil
}
// RestrictedHandler for /r
func RestrictedHandler(c *routing.Context) error {
c.Response.Header.Set("content-type", "application/json")
pricipalObj, extractError := extractPricipalObject(c)
if extractError != nil {
loggermdl.LogError(extractError)
_, err := c.WriteString(extractError.Error())
c.SetStatusCode(412)
return err
}
pricipalObj.ClientIP = c.RemoteIP().String()
commonHandler(c, true, false, false, pricipalObj)
return nil
}
// RoleBasedHandler for /r/c
func RoleBasedHandler(c *routing.Context) error {
c.Response.Header.Set("content-type", "application/json")
pricipalObj, extractError := extractPricipalObject(c)
if extractError != nil {
loggermdl.LogError(extractError)
_, err := c.WriteString(extractError.Error())
c.SetStatusCode(412)
return err
}
pricipalObj.ClientIP = c.RemoteIP().String()
commonHandler(c, true, true, false, pricipalObj)
return nil
}
// HeavyOpenHandler for /o
func HeavyOpenHandler(c *routing.Context) error {
c.Response.Header.Set("content-type", "application/json")
principal := servicebuildermdl.Principal{}
principal.ClientIP = c.RemoteIP().String()
commonHandler(c, false, false, true, principal)
return nil
}
// HeavyRestrictedHandler for /r
func HeavyRestrictedHandler(c *routing.Context) error {
c.Response.Header.Set("content-type", "application/json")
pricipalObj, extractError := extractPricipalObject(c)
if extractError != nil {
loggermdl.LogError(extractError)
_, err := c.WriteString(extractError.Error())
c.SetStatusCode(412)
return err
}
pricipalObj.ClientIP = c.RemoteIP().String()
commonHandler(c, true, false, true, pricipalObj)
return nil
}
// HeavyRoleBasedHandler for /r/c
func HeavyRoleBasedHandler(c *routing.Context) error {
c.Response.Header.Set("content-type", "application/json")
pricipalObj, extractError := extractPricipalObject(c)
if extractError != nil {
loggermdl.LogError(extractError)
_, err := c.WriteString(extractError.Error())
c.SetStatusCode(412)
return err
}
pricipalObj.ClientIP = c.RemoteIP().String()
commonHandler(c, true, true, true, pricipalObj)
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
return nil
}
func appVersioning(c *routing.Context) error {
if isAppVersionEnabled {
appVersion := string(c.Request.Header.Peek("app-version"))
if appVersion == "" {
return errormdl.Wrap("No App version Found in request header")
}
ver, err := version.NewVersion(appVersion)
if errormdl.CheckErr(err) != nil {
return errormdl.CheckErr(err)
}
if isStrictMode {
if !ver.Equal(applicationVersion) {
return errormdl.Wrap("Application version mismatched")
}
} else {
if ver.GreaterThan(applicationVersion) {
return errormdl.Wrap("Server Version is outdated")
}
if ver.LessThan(minimumSupportedVersion) {
return errormdl.Wrap("Client Version is outdated")
}
}
}
return nil
}
func extractPricipalObject(c *routing.Context) (servicebuildermdl.Principal, error) {
principal := servicebuildermdl.Principal{}
if jwtmdl.GlobalJWTKey == "" {
return principal, errormdl.Wrap("No Global JWT key found")
}
claim, decodeError := jwtmdl.DecodeToken(&c.Request)
if errormdl.CheckErr(decodeError) != nil {
// loggermdl.LogError(decodeError)
return principal, errormdl.CheckErr(decodeError)
}
groups, grperr := roleenforcemdl.GetGroupNames(claim, "groups")
if errormdl.CheckErr(grperr) != nil {
loggermdl.LogError(grperr)
return principal, errormdl.CheckErr(grperr)
}
userID, _ := claim["userId"].(string)
// if !ok {
// loggermdl.LogError("Unable to parse UserID from JWT Token")
// return principal, errormdl.Wrap("Unable to parse UserID from JWT Token")
// }
if len(userID) < 2 {
loggermdl.LogError("UserID length is less than 2")
return principal, errormdl.Wrap("UserID length is less than 2")
}
rawMetadata, ok := claim["metadata"]
if ok {
metadata, ok := rawMetadata.(string)
if !ok {
loggermdl.LogError("Unable to parse metadata from JWT Token")
return principal, errormdl.Wrap("Unable to parse metadata from JWT Token")
}
principal.Metadata = metadata
}
principal.Groups = groups
principal.UserID = userID
principal.Token = string(c.Request.Header.Peek("Authorization"))
return principal, nil
351352
}